jvm参数优化

发布时间 2023-06-19 00:19:13作者: MarkLeeBYR

-XX:-UseStringDeduplication

作用

关闭字符串去重,减少CPU开销。-XX:+UseStringDeduplication 对比验证

使用场景

JAVA程序 容器云实例都需要配置。修改服务模板中的配置,把服务模板中的 -XX:+UseStringDeduplication 改为 -XX:-UseStringDeduplication

类别

CPU优化,加权平均优化0.77%


 

-XX:-G1UseAdaptiveIHOP

作用

使用配置的InitiatingHeapOccupancyPercent作为concurrent marking的触发条件,即老年代占总堆内存的比例。如果没有配置此参数,G1默认会动态计算IHOP值,而我们在实践中发现G1计算的值有时并不合理,会导致频繁的concurrent marking和mixed gc消耗大量cpu

202108 API集群性能分析

关于comment-cache-setter老年代对象较多的问题

类别

CPU优化

-XX:OnOutOfMemoryError="/opt/kbox/latest/dropin/notify_oome"

作用

You can use this Oracle HotSpot option to run commands when a java.lang.OutOfMemoryError is thrown.

内存溢出回调配置,调用配置的脚本 /opt/kbox/latest/dropin/notify_oome

使用场景

JAVA程序 容器云实例都需要配置

notify_oome — Kuaishou JDK Troubleshooting Guide 1.0.0 documentation

类别

问题排查


 

-XX:ErrorFile=/home/web_server/kuaishou-tomcat/log/hs_err_pid%p.log

作用

If an error occurs, save the error data to this file

JAVA程序异常退出时候,保留一些日志供后续分析

使用场景

JAVA程序 容器云实例都需要配置,KsBoot等runner路径有所区别

类别

问题排查


 


-XX:-PreserveFramePointer

作用

  • 类似于GCC的 -fomit-frame-pointer 选项,PreserveFramePointer选项会将函数调用的frame pointer保存至寄存器,给perf等基于backtrace获取完整调用堆栈的场景提供支持,但同时也额外多执行了一些指令,引入一定开销。 经过线上实际场景的对比,此参数带来的性能损失为1% - 3%

  • PreserveFramePointer在openjdk中默认关闭,在快手snowman jdk中,因为perf、kb-nmp-mallct等native调测工具的使用需要,默认开启了此选项。

  • JVM自身提供的jvmti接口,可以在不依赖PreserveFramePointer的情况下,获取Java堆栈,构建在其之上的jstack、async-profiler(AsyncGetCallTrace) 等工具也都不依赖PreserveFramePointer.

  • 鉴于 「使用native工具获取Java堆栈 」这种场景出现的频率低,而常用JVM诊断工具均不依赖此参数,可以考虑仅在有限环境下开启PreserveFramePointer

副作用

无法获取native层堆栈

使用场景

snowman jdk下,程序性能优化,不需要采集相关堆栈信息

类别

CPU优化,比例1% - 3%


 


-XX:+IgnoreUnrecognizedVMOptions

作用

This Oracle option affects the behavior of the HotSpot JVM when it finds an unrecognized top-level option at startup.

当在启动时发现无法识别的顶级选项,忽略出现的Unrecognized VM option异常

副作用

忽略的选项可能是需要关心的

使用场景

按需使用,添加后兼容性高一些,不添加需要严格管控启动参数

类别

启动优化


 


-XX:+ExtendThreadStatisticalInfo

作用

开启监控上报,能够细致的分析不同阶段cpu的开销

监控地址: https://grafana.corp.kuaishou.com/d/f0Z8TNz7z/jvmnei-bu-perfmian-ban?orgId=3&refresh=30s

使用场景

kBox版本特性,建议开启

类别

问题排查


 

-XX:+ExplicitGCInvokesConcurrent

如果不设置,那么System.gc就是单线程的full gc,建议设置。

-XX:-DisableExplicitGC

不禁用System.gc,jvm在堆外内存不够时,会尝试使用System.gc回收内存,如果disable了,就无法回收。

建议和-XX:+ExplicitGCInvokesConcurrent一起使用。


 

大页优化相关参数

-XX:G1HeapResizePolicy=off

-XX:+AlwaysPreTouch

-XX:+UseLargePages -XX:+UseTransparentHugePages

-XX:MallocExt=je

-XX:MallocExtConf=tcache:true,dirty_decay_ms:10000,muzzy_decay_ms:10000,reserve_size:6g,retain:false,dss:primary

作用

-XX:MallocExtConf

详见:https://infra-kbox.corp.kuaishou.com/vmfarm/docs/kjtg/chapter-03/section-01/subsection-13.html

  • 堆外reserve_size 的大小,可以根据服务具体情况设置,设置方式见上面的文档

  • 堆外jeopt(jemalloc optimization)(弹性堆外)

  • kbox的默认的参数下,满足GC SLA的前提下,尽可能地将不用的内存归还给操作系统,让监控的内存rss的指标得到改善。如果是优化cpu的话,我们现在的方案是把内存reserve住,避免归还内存引发的spike。预期会导致内存rss指标有增加

  • 默认打开,关闭弹性推外也可以优化一些CPU消耗。dirty_decay_ms:-1,muzzy_decay_ms:-1,可以关闭


 

-XX:+AlwaysPreTouch

参考:https://www.jianshu.com/p/a8356d03ac8f

优点:在启动时把所有参数定义的内存全部捋一遍。使用这个参数可能会使启动变慢,但是在后面内存使用过程中会更快。可以保证内存页面连续分配,新生代晋升时不会因为申请内存页面使GC停顿加长。通常只有在内存大于32G的时候才会有感觉。

缺点:启动时间拉长


 

-XX:MallocExt=je

https://infra-kbox.corp.kuaishou.com/vmfarm/docs/kjtg/chapter-03/section-01/subsection-14.html


 

-XX:+UseLargePages -XX:+UseTransparentHugePages

开启内存大页,向应用程序透明地提供大页面存储支持


 

注意

大页使用,需要物理机也打开THP

类别

CPU优化,效果5%-15%之间


 


系统属性&变量设置

-Dkconf.client.mutationMonitorEnable=true (已于21年推全并删除此变量)

* 对 Kconf 持有的 List/Set/Map 的修改操作进行监控

* 从而发现用户错误修改 Kconf 持有全局对象导致的 bug

类别

问题排查


 

-Ddynamic-logger-level-kconf=webserver.dynamicLogger.api

主站api 日志动态化配置

https://kstack.corp.kuaishou.com/article/2696

类别

问题排查


 


-DdisablePerfAgent=true

禁用 PerfAgent 加快启动速度

PerfAgent支持在方法上打上注解(@Perf,@Trace),然后收集对应的执行时间。这个功能没有依赖Spring的AOP,使用的是字节码技术,底层是ByteBuddy。

ByteBuddy对有注解的类做了增强,因此每次加载类都会走ByteBuddy的判断逻辑,加载的类较多时(7w+),性能影响比较大。

https://kstack.corp.kuaishou.com/article/4311

PerfAgent对启动速度的影响

类别

启动效率


 

-DALLOW_KUAISHOU_INDEX=true

Spring Config Scan Bean优化:kuaishou-spring-context-indexer

  1. 是否使用编译期生成的META-INF/kuaishou.components来扫描bean(spring context indexer)

  2. 默认是关闭的,设置为true开启

  3. 目前对于kotlin写的bean,不兼容,会出现找不到bean的情况

  4. 建议开启,可以加快spring启动约1min左右

类别

启动效率


 


-Djdk.jarindex.disableJarIndexValidation=true

Jar包 INDEX.LIST索引

Jar Index 接入指南

  1. 构建镜像时,勾选了klib(只支持tomcat应用,容器云部署的),建议加上这个参数

  2. 主要作用是,减少jar index validate带来的开销

类别

启动效率


 


-DIGNORE_EVENTLISTENER_LAZYBEAN=true

EventListener注解处理bug

Spring Config Scan Bean优化:kuaishou-spring-context-indexer

  1. 是否跳过lazy bean上的event listener注解处理

  2. 默认是关闭,设置为true开启

  3. 慎重开启,可以加快spring启动

  4. 开启前,需要确认不影响EventListener相关的逻辑

类别

启动效率


 


-DWARMUP_PARALLEL_THREADS=50

在infra新的warmup框架中,用于控制warmup的线程数,默认是1

  1. 设置过小,会导致有些资源没有warmup到,服务P995升高,tomcat线程池使用率瞬间上升

  2. warmup的监控

类别

启动效率


 

-DDISABLE_PERF_LOG_LOCAL=true

关闭logLocal,通过PerfUtils打的perf不输入到perfs.log文件中,节省cpu性能。

perf关闭perf local线上效果分析

类别

CPU优化


 

REGISTER_TO_KNS_BEFORE_PREHEAT_READY

接入smooth warmup的系统,需要配置REGISTER_TO_KNS_BEFORE_PREHEAT_READY或者ksp_service_name

作用是在预热ready之前,将系统注册到kns,触发kns的探活。主要是为了解决下面的问题:

  1. 没有提前注册至kns,就无法收集到nginx的ip,smooth无法正常工作,只能以超时结束

  2. 加快kcsize探活时间。

如果没有提前注册,smooth爬坡过程收集不到nginx的ip信息,最终是以超时的形式结束的,默认的超时时间是3min。

如果提前注册了,那就是正常爬坡结束之后,kcsize探活成功,时间就是配置的爬坡时间。

节省的时间 = 预热超时时间 - 爬坡时间

有些系统配置的时候,只配置了爬坡时间,比如40s,但是没有配置超时时间(取默认值3min),同时叠加上没有提前注册,就会导致3min - 40s = 140s的耗时增长


 

11、API接入smooth warmup

主站技术部api服务没有配置的集群:KSN服务明细ksboot-api&tomcat


 

目前存在两种BaseStatusController,一种是新做的在kuaishou-web-common-basic.jar,一种是在kuaishou-component-split-common.jar。

这两种实现上对fromKsp的定义不同,kuaishou-web-common-basic中的版本,排除了127.0.0.1和query param中携带的fromKsp;

component-split中没有处理这个,一般是StatusController中自己处理的,一般会处理fromKsp参数,不会处理127.0.0.1。

zt-web-common中的StatusController处理了这个:


 

这两种差别,在没有配置REGISTER_TO_KNS_BEFORE_PREHEAT_READY或者ksp_service_name时,分别表现为:

  • kuaishou-web-common-basic一直没有收集到nginx ip,爬坡以超时结束

  • kuaishou-component-split-common.jar收集到了127.0.0.1,以为是nginx的ip,以成功预热结束(但是只爬坡了127.0.0.1)


 

在正确配置了REGISTER_TO_KNS_BEFORE_PREHEAT_READY时,都能正常爬坡


 

类别

启动效率


 

SUPERVISOR_PROGRAM0_STOPWAITSECS

强制停止时延。推荐值:300

容器尝试退出时,会先发送SIGTERM(15      TERM (software termination signal))给应用,应用此时会处理TermHelp注册的hooks,然后调用jvm的shutdown hooks。

优雅停机就是依赖这个机制实现的。

有些异常的情况下,这个过程会超时,容器会等待<强制停止时延>中配置的时间,如果此时进程还在,则发送KILL信号(9  KILL (non-catchable, non-ignorable kill))。

在故障期间,遇到过这个值配置的过大,应用一直full gc,导致重启特别慢的情况。

类别: 启动效率


 

GC相关参数

参数

说明

备注

MaxRAMPercentage

60

设置初始堆最大堆占总内存比例,如果设置了-Xmx,该参数不起作用


 

InitialRAMPercentage

60

设置初始堆大小占总内存比例,如果配置了-Xms,该参数不起作用


 

MetaspaceSize

1G

元空间多次扩容后超过此值,会触发fullGc


 

MaxMetaspaceSize

1G

元空间最大大小,默认和MetaspaceSize相同


 

Xss

512k

每个线程的堆栈大小


 

ReservedCodeCacheSize

720M

用于设置Reserved code cache的最大大小,通常默认是240M

不同服务不一样,主站API服务统一是720M,JIT编译的代码都放在Code Cache,主站这边是单体大项目,所以设置的比较大

MaxDirectMemorySize

4G


 

不同服务不一样

G1NewSizePercent

30

G1新生代比例最小值


 

MaxGCPauseMillis

200

GC最大暂停时间(毫秒)

部分对延迟不敏感的服务可以修改,比如可以设置为500,800等,可以增加吞吐(批处理任务较为合适)

InitiatingHeapOccupancyPercent

45

总堆内存占用达到该阈值,会开始并发标记周期

调大可以减少mix gc产生,相应的有oom风险;调小会更快的开始并发标记周期,可能产生更多的mix gc

G1ReservePercent

20

堆保留的比例,预留一部分空间防止to-space溢出