分布式技术专题「系统服务优化系列」web应用服务的性能指标优化开发指南(jvm篇)(代码片段)

洛神灬殇 洛神灬殇     2023-01-06     267

关键词:

JVM优化机制

JIT编译器相关的优化

对JVM性能影响最大的是编译器,选择编译器是运行 java 程序首先要做的选择之一

热点编译的概念

对于程序来说,通常只有一部分代码被经常执行,这些关键代码被称为应用的热点,执行
的越多就认为是越热。将这些代码编译为本地机器特定的二进制码,可以有效提高应用性能

热点编译的种类

hotspot jvm 内置了两个jit编译器,分别是client compiler(C1编译器)和server compiler(C2编译器),可通过下列指令显式指定使用哪种即时编译器。

选择编译器类型

  • -server,更晚编译,但是编译后的优化更多,性能更高 - 采用C2编译器
  • 特点:C2进行较长时间的优化,以及激进优化。但优化的代码执行效率更高

  • -client,很早就开始编译 C1编译器
    特点:C1编译器会堆字节码进行简单和可靠的优化,耗时短。以达到更快的编译速度

  • -XX:+TieredCompilation开启分层编译可以让jvm在启动时启用client编译,随着代码变热后再转为server编译缺省编译器取决于机器位数、操作系统和 CPU 数目。32 位的机器上,一般默认都是client 编译,64 位机器上一般都是 server 编译,多核机器一般是server编译。

图中的mix mode 一般指编译时机:

  • -Xint,表示禁用 JIT,所有字节码都被解释执行,这个模式的速度最慢的
  • -Xcomp 表示所有字节码都首先被编译成本地代码,然后再执行
  • -Xmixed(默认),让 JIT 根据程序运行的情况,有选择地将某些代码编译成本地代码
  • -Xcomp 和-Xmixed 到底谁的速度快,针对不同的程序可能有不同的结果,基本还是推荐
    用默认模式

代码缓存相关

在编译后,会有一个代码缓存区,保存编译后的代码,一旦这个缓存满了,jvm 将无法继续编译代码。

当提示:CodeCache is full,表示需要增加代码缓存。–XX:ReservedCodeCacheSize=N 可以用来调整这个大小


编译阈值

代码是否进行编译,取决于代码执行的频度,是否到达编译阈值。

计数器有两种:方法调用计数器和方法里的循环回边计数器,一个方法是否达到编译阈值取决于方法中的两种计数器之和

编译阈值调整的参数为:-XX:CompileThreshold=N

  • 方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间之内方法被调用的次数
  • 当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay),而这段时间就称为此方法统计的半衰周期(Counter Half Life Time)
  • 进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数-XX:-UseCounterDecay 来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译成本地代码

另外,可以使用 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒。
与方法计数器不同,回边计数器没有计数热度衰减的过程,因此这个计数器统计的就是该
方法循环执行的绝对次数。

编译线程

进行代码编译的时候,是采用多线程进行编译的。

方法内联

  • 内联默认开启,-XX:-Inline,可以关闭,但是不要关闭,一旦关闭对性能有巨大影响
  • 方法是否内联取决于方法有多热和方法的大小
  • **很热的方法如果方法字节码小于 325 字节才会内联,这个大小由参数 - XX:MaxFreqInlinesSzie=N 调整,这个很热与热点编译不同,没有任何参数可以调整热度 ** 。
  • 方法小于 35 个字节码,一定会内联,这个大小可以通过参数-XX:MaxInlinesSzie=N 调整

逃逸分析

是 JVM 所做的最激进的优化,最好不要调整相关的参数。

GC 调优

  • GC 的时间够小
  • GC 的次数够少

发生 Full GC 的周期足够的长,时间合理,最好是不发生。

调优的原则和步骤

  1. 大多数的 java 应用不需要GC调优
  2. 大部分需要 GC 调优的的,不是参数问题,是代码问题
  3. 在实际使用中,分析GC情况优化代码比优化 GC 参数要多得多;
  4. GC 调优是最后的手段

GC 调优的最重要的三个选项:

  1. 第一位:选择合适的 GC 回收器
  2. 第二位:选择合适的堆大小
  3. 第三位:选择年轻代在堆中的比重

步骤

  • 1,监控 GC 的状态

使用各种 JVM 工具,查看当前日志,分析当前 JVM 参数设置,并且分析当前堆内存快照
和 gc 日志,根据实际的各区域内存划分和 GC 执行时间,觉得是否进行优化;

  • 2,分析结果,判断是否需要优化

如果各项参数设置合理,系统没有超时日志出现,GC 频率不高,GC 耗时不高,那么没有必要进行 GC 优化;如果 GC 时间超过 1-3 秒,或者频繁 GC,则必须优化;

注:如果满足下面的指标,则一般不需要进行 GC优化:

  • Minor GC 执行时间不到 50ms;
  • Minor GC 执行不频繁,约 10 秒一次;
  • Full GC 执行时间不到 1s;
  • Full GC 执行频率不算频繁,不低于 10 分钟 1 次;

调整 GC 类型和内存分配

如果内存分配过大或过小,或者采用的 GC 收集器比较慢,则应该优先调整这些参数,并且先找 1 台或几台机器进行 beta,然后比较优化过的机器和没有优化的机器的性能对比,并有针对性的做出最后选择;

不断的分析和调整

通过不断的试验和试错,分析并找到最合适的参数

全面应用参数

如果找到了最合适的参数,则将这些参数应用到所有服务器,并进行后续跟踪。
学会阅读 GC 日志

以参数 -Xms5m -Xmx5m -XX:+PrintGCDetails -XX:+UseSerialGC 为例:

[DefNew: 1855K->1855K(1856K), 0.0000148 secs][Tenured: 2815K->4095K(4096K),
0.0134819 secs] 4671K

  • DefNew 指明了收集器类型,而且说明了收集发生在新生代。
  • 1855K->1855K(1856K)表示,回收前 新生代占用 1855K,回收后占用 1855K,新生代大
    小 1856K。
  • 0.0000148 secs 表明新生代回收耗时。
  • Tenured 表明收集发生在老年代
  • 2815K->4095K(4096K), 0.0134819 secs:含义同新生代,最后的 4671K 指明堆的大小。

收集器参数变为-XX:+UseParNewGC,日志变为:

[ParNew: 1856K->1856K(1856K), 0.0000107 secs][Tenured: 2890K->4095K(4096K),
0.0121148 secs]

收集器参数变为-XX:+ UseParallelGC 或 UseParallelOldGC,日志变为:

[PSYoungGen: 1024K->1022K(1536K)] [ParOldGen: 3783K->3782K(4096K)]4807K->4804K(5632K),

CMS 收集器和 G1 收集器会有明显的相关字样
其他与 GC 相关的参数
调试跟踪之 打印简单的 GC 信息 参数:

  • -verbose:gc
  • -XX:+PrintGC

打印详细的 GC 信息

  • -XX:+PrintGCDetails

  • +XX:+PrintGCTimeStamps

  • -Xloggc:logpath 设置 gc 的日志路,如: -Xlogger:log/gc.log, 将 gc.log 的路径设置到当前目录的 log 目录下.应用场景: 将 gc 的日志独立写入日志文件,将 GC日志与系统业务日志进行了分离,方便开发人员进行追踪分析。

  • -XX:+PrintHeapAtGC, 打印推信息

  • 参数设置: -XX:+PrintHeapAtGC

  • 应用场景: 获取 Heap 在每次垃圾回收前后的使用状况

  • -XX:+TraceClassLoading

  • 参数方法: -XX:+TraceClassLoading

  • 应用场景: 在系统控制台信息中看到 class 加载的过程和具体的 class 信息,可用以分析类的加载顺序以及是否可进行精简操作。

  • -XX:+DisableExplicitGC 禁止在运行期显式地调用 System.gc()

  • -XX:-HeapDumpOnOutOfMemoryError 默认关闭,建议开启,在

  • java.lang.OutOfMemoryError 异常出现时,输出一个 dump.core 文件,记录当时的堆内存快照。

  • -XX:HeapDumpPath=./java_pid.hprof 默认是 java 进程启动位置,用来设置堆内存快照的存储文件路径。

  • -XX:OutOfMemoryError=<指令路径>

推荐策略

年轻代大小选择

0· 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).
在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象.吞吐量优先的应用:尽可能的设置大,可能到达 Gbit 的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合 8CPU 以上的应用. · 避免设置过小.当新生代设置过小时会导致:

  1. YGC 次数更加频繁
  2. 可能导致 YGC 对象直接进入旧生代,如果此时旧生代满了,会触发 FGC.

年老代大小选择

  1. 响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发
    会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎 片,高回收频率以及
    应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.最优化的方案,一
    般需要参考以下数据获得:
    并发垃圾收集信息、持久代并发收集次数、传统 GC 信息、花在年轻代和年老代回收上的
    时间比例。
  2. 吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原
    因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对

2.18-2.24博客精彩回顾

...文件​​12.​​性能瓶颈分析方法论​​13.​​OpenHarmony分布式相机(上)​​14.​​MyBatis支持多种数据库连接(多种sql语法支持)​​15.​​flutter系列之:在flutter中使用导航Navigator​​​二、专题推荐1.​​后端开发专题系列​... 查看详情

分布式技术专题「oss中间件系列」minio的server端服务的架构和实战搭建(代码片段)

...tStorage我目前的理解就是数据存储,minio可以用来搭建分布式存储服务Minio是ApacheLicensev2.0下发布的对象存储服务器。它与AmazonS3云存储服务兼容。它最适合存储非结构化数据,如照片,视频࿰ 查看详情

分布式技术专题「oss中间件系列」minio的文件服务的存储模型及整合java客户端访问的实战指南(代码片段)

Minio的元数据数据存储MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是:个别对象的失效,不会溢出为更大级别的系统失效。便于实现“强一致性”这个特性。此特性对于机... 查看详情

饿了么分布式服务治理及优化经验(含ppt)

饿了么分布式服务治理及优化经验(含PPT)导读:高可用架构7月30日在上海举办了『互联网架构的基石』专题沙龙,进行了闭门私董会研讨及对外开放的四个专题的演讲,期望能促进业界对互联网基础架构的建设及发展,本文是... 查看详情

分布式技术专题「lvs负载均衡」全面透析web基础架构负载均衡lvs机制的原理分析指南

前提概要在大规模互联网应用中,负载均衡设备是必不可少的组成部分,源于互联网应用的高并发和大流量的冲击压力场景下,通常会在服务端部署多个无状态的应用服务器和若干有状态的存储服务器(数据库、缓存等等)实现... 查看详情

分布式技术专题「lvs负载均衡」全面透析web基础架构负载均衡lvs机制的原理分析指南(代码片段)

前提概要在大规模互联网应用中,负载均衡设备是必不可少的组成部分,源于互联网应用的高并发和大流量的冲击压力场景下,通常会在服务端部署多个无状态的应用服务器和若干有状态的存储服务器(数据库、... 查看详情

优化技术专题「系统性能调优实战」终极关注应用系统性能调手册指南(上册)

...力和层次,所以便进行先关系统性质的学习和优化相关的技术做了一定的研究。调优背景因为当出现吞吐远远不能够满足我们客户或者我们需要的呼叫了指标的时候因为出现了这么一次情况,虽然没有给用户没有给公司带来什么... 查看详情

分布式技术专题「oss中间件系列」从0到1的介绍一下开源对象存储minio技术架构

...器之间采用http/https通信协议。GlusterfsGlusterfs是一个开源分布式文件系统,具有强大的横向扩展能力,可支持数PB存储容量和数千客户端,通过InfinibandRDMA或Tcp/Ip方式将许多廉价的x86主机&# 查看详情

1.28-2.3博客精彩回顾

...​​14.​​LinuxALSA驱动之二:声卡的创建流程​​15.​​分布式事务2种协议及4种模式​​​二、专题推荐1.​​Python专题系列​​2.​​网络/安全专题系列​​3.​​系统/运维专题系列​​4.​​Java专题系列​​5.​​云计算专... 查看详情

权限设计系列「认证授权专题」微服务架构的登陆认证问题

...知识本文讨论基于微服务架构下的身份认证和用户授权的技术方案,最好先熟悉并理解以下几个知识点:微服务架构相关概念:服务注册、服务发现、API网关身份认证和授权技术:SSO、CAS、OAuth2.0、JWT以下几个基... 查看详情

分布式技术专题「oss中间件系列」minio的文件服务的存储模型及整合java客户端访问的实战指南(代码片段)

Minio的元数据数据存储MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是:个别对象的失效,不会溢出为更大级别的系统失效。便于实现“强一致性”这个特性。此特性对于机... 查看详情

alibaba中间件技术系列「nacos技术专题」服务注册与发现相关的原理分析

Nacos的概览Nacos/nɑ:kəʊs/是DynamicNamingandConfigurationService的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助... 查看详情

分布式技术专题「架构设计方案」盘点和总结秒杀服务的功能设计及注意事项技术体系

秒杀应该考虑哪些问题超卖问题分析秒杀的业务场景,最重要的有一点就是超卖问题,假如备货只有100个,但是最终超卖了200,一般来讲秒杀系统的价格都比较低,如果超卖将严重影响公司的财产利益,因此首当其冲的就是解决... 查看详情

alibaba微服务技术系列「dubbo3.0技术专题」总体技术体系介绍及技术指南(序章)

Dubbo的背景介绍Dubbo的功能特性面向接口代理的高性能RPC调用;服务自动注册与发现;智能负载均衡策略;高度可扩展能力;运行期流量调度;可视化的服务治理与运维;Dubbo的框架结构Dubbo的发展历程2011/10/27:阿里巴巴巴宣布Dub... 查看详情

优化技术专题「系统性能调优实战」终极关注应用系统性能调优及原理剖析(下册)

前提介绍承接上文:【优化技术专题】「系统性能调优实战」终极关注应用系统性能调优及原理剖析(上册)之后我们接下来进行相关的。流程相关分析优化通过access_log.txt日志分析,在特定时间段内,将请求至系统的url分组计... 查看详情

入门」全方位盘点和总结调优技术专题指南

专题⽬标本系列专题的目标是希望可以帮助读者们系统和全访问掌握应⽤系统调优的思路与方案以及相关的调优工具的使用,虽然未必会覆盖目前的所有的问题场景,但是还是提供了较为丰富的案例和调优理论,会帮助大家打开... 查看详情

分布式技术专题「架构实践于案例分析」盘点分布式服务的(无状态有状态)认证实现方案

⽆状态vs有状态有状态、⽆状态是什么有状态:服务器端需要保存请求的相关信息,每个请求可以默认地使⽤以前的请求信息⽆状态:服务器端不记录请求的相关信息,服务器处理的内容完全来⾃请求所携带的信息,以及其他服... 查看详情

技术架构文章汇总

前言(1):服务端高并发分布式架构演进之路前言(2):什么是微服务?前言(3):分布式的坑1.大型网站架构演化2.大型网站架构演化的价值观3网站架构设计误区4网站架构模式5大型网站核心架构要素6网站性能测试7Web前端性能优化8应... 查看详情