JVM调优-配置参数
什么时候需要调优
- 非计算密集型任务cpu占用过高
- 老年代已使用空间大于70%
- Full GC频繁
- 单次GC时间大于1秒
- 出现OOM
- 程序的响应速度明显变慢
示例情况
非计算密集型任务cpu占用过高:有用户线程cpu过高、gc线程cpu过高。用户线程cpu过高一般是出现了死循环,需要查看线程堆栈、结合arthas的watch命令等找出问题根源。gc线程过高一般是Full GC频繁,Full GC频繁一般是因为老年代或方法区(元空间)内存不足。需要对gc日志分析、对堆转储文件分析,确定是哪些对象实例占用了过多内存、反射的类是否过多、被多个类加载器加载的类是否过多等,决定是增加内存大小还是对源码进行处理等。
老年代已使用空间大于70%:有可能发生了内存泄漏、有可能是设置的堆大小无法满足正常业务的需求。需要对堆转储文件分析,确定是哪些对象实例占用了过多内存,并检查是否发生了内存泄漏。对堆大小无法满足正常业务的需求,应调大堆大小,通过-Xms和-Xmx来设置。
Full GC频繁:Full GC频繁一般是因为老年代或方法区(元空间)内存不足。需要对gc日志分析、对堆转储文件分析,确定是哪些对象实例占用了过多内存、反射的类是否过多、被多个类加载器加载的类是否过多等,决定是增加内存大小还是对源码进行处理等。
单次GC时间大于1秒:
1、老年代内存过大。老年代中累积了大量对象时才触发full gc,这次gc的任务很重,耗费的时间很长。通过测试,选择一个合适的老年代大小。
2、年轻代过小。年轻代过小,当年轻代空间不足时对象就会分配到老年代,而这些对象可能是“短命”的,但会停留在老年代很久。当full gc时,gc的任务会很重。因此,可以增大年轻代的大小。通过增大-XX:MaxTenuringThreshold=n来设置对象的晋升到老年代的年龄门槛,减缓对象进入老年代。
3、创建对象的速度过快。对创建对象过快的代码进行优化,防止短时间内大量创建对象,以致年轻代空间不足而提前进入老年代。
4、gc线程数过少。gc线程数过少,无法充分利用多核cpu的并行处理。gc日志中 user、sys、real时间需要关注。若real时间 与 (user时间/gc线程数+sys)相差不远,则gc线程数合适。
5、进程被swap出内存。当物理内存不足时,系统会将一些内存存于磁盘的swap区,而swap区的访问速度慢很多。检查进程是否被放到swap区了,若是,应该增大物理内存,减少其他进程对内存的占用。
6、合适的垃圾收集器。若非jvm专家,建议使用G1。通过-XX:MaxGCPauseMillis来设置最大停顿时间。出现OOM:老年代或方法区(元空间)内存不足即是堆内存异常、栈内存异常。开启-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=。利用mat(memory analizer tool)对堆转储文件进行分析,确定是哪些对象实例占用了过多内存、反射的类是否过多、被多个类加载器加载的类是否过多等,决定是增加内存大小还是对源码进行处理等。
程序的响应速度明显变慢:检查是否存在上面的四种情况或可能出现了死锁。
JVM参数调优
堆大小设置
JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64位操作系统对内存无限制。
示例如下:
1. java -Xmx3550m -Xms3550m -Xmn2g -Xss128k。
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM最小内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
2. java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
-XX:MaxPermSize=16m:设置持久代大小为16m。
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概率。
回收器选择
JVM给了三种选择:串行收集器、并行收集器、并发收集器。但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数。JDK5.0以后,JVM会根据当前系统配置进行判断。
CMS与G1的选择
服务器资源充足:选择G1服务器资源不充足:选择CMS
吞吐量优先的并行收集器
并行收集器主要以到达一定的吞吐量为目标。
典型配置:
1.java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
2.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。
3.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100
-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。
4.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。
- 响应时间优先的并发收集器
并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。
典型配置:
1.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此时年轻代大小最好用-Xmn设置。
-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值。
2.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。
-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片
参数调优总结
年轻代大小选择
- 响应时间优先的应用:
尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。 - 吞吐量优先的应用:
尽可能的设置大,可能到达Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。
年老代大小选择
响应时间优先的应用:
年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:减少年轻代和年老代花费的时间,一般会提高应用的效率并发垃圾收集信息
持久代并发收集次数
传统GC信息
花在年轻代和年老代回收上的时间比例吞吐量优先的应用:
一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。较小堆引起的碎片问题:
因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
-XX:MaxHeapFreeRatio=30
此文章作为JVM调优笔记,来源素材如下:
https://blog.csdn.net/feiying0canglang/article/details/124943670
https://blog.csdn.net/qq_39989608/article/details/122838542
配置参数:https://blog.csdn.net/baidu_28068985/article/details/126468686
JVM调优-配置参数相关推荐
- JVM调优和参数配置
1.JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots 答:什么是垃圾:简单的说就是内存中已经不再被使用到的空间就是垃圾 要进行垃圾回收,如何判断一个对象是否可以被回 ...
- JVM调优及参数设置
(1)参数 -Xms:初始堆大小 -Xmx :最大堆大小 此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存 -Xmn :年轻代大小 整个堆大小=年轻代大小 + 年老代大小 + 持 ...
- JVM调优常用参数配置
2019独角兽企业重金招聘Python工程师标准>>> 堆配置 -Xms:初始堆大小 -Xms:最大堆大小 -XX:NewSize=n:设置年轻代大小 -XX:NewRatio=n: ...
- JVM调优-GC参数
一.Throughput收集器(吞吐量) -XX:+UseParallelGC -XX:+UseParallelOldGC *参数调整:通过调整堆大小,减少GC停顿时间,增大吞吐量 增强堆大小可以减少 ...
- JVM调优之参数配置: -Xms -Xmx -Xmn -XX:+PrintGCDetails -XX:UseSerialGC -XX:SurvivorRadio -XX:NewRadio
JVM提供了诸多的参数进行JVM各个方面内存大小的设置,为Java应用进行优化提供了诸多的工具,本文将会详细分析各个参数的功能与使用. 1.常见参数说明: -Xms: //堆内存初始化大小 -Xmx: ...
- JVM的进阶学习(GC Roots、JVM调优与参数配置、)
1. GC Roots,可达性分析 从GC roots的对象作为起始点,从GC Roots对象开始向下搜索,如果一个对象到GCRoots没有任何引用链相连,则说明对象不可用.即给定一个集合的引用作为根 ...
- java面试-JVM调优和参数配置
JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式 -Xint 解释执行 -Xcomp 第一次使用就编译成本地代码 3.XX ...
- 【JVM】JVM调优常见参数详解
原文出处: https://blog.csdn.net/jyxmust/article/details/73730766 -Xms2g:JVM启动初始化堆大小为2g,Xms的默认是物理内存的1/64但 ...
- 常用的 jvm 调优的参数都有哪些?
(1)-Xms20M 表示设置JVM启动内存的最小值为20M,必须以M为单位 (2)-Xmx20M 表示设置JVM启动内存的最大值为20M,必须以M为单位.将-Xmx和-Xms设置为一样可以避免JVM ...
最新文章
- jieba分词流程及部分源码解读(一)
- ios app 砸壳
- 2021年春季学期-信号与系统-第四次作业参考答案-第三小题
- signature=ecbb5c28a0561484700bbfeebe84cc52,Corps next in line as bond fees are hit by ECB
- 网站建设难?三个技巧来帮你!
- 人为什么总感觉莫名的心烦?
- 如何使用 Weave 网络?- 每天5分钟玩转 Docker 容器技术(63)
- HDOJ2003求绝对值
- 演练:使用 Windows 窗体收集数据
- 更新maven卡在18不动_Android Studio maven-metadata.xml 卡着不动原因和解决方法
- 如何避免PayPal、Fb、谷歌账户被封,又如何解封?
- CIKM 2019 挑战杯「用户行为预测」冠军方案:层次GNN模型在推荐中的应用
- 利用telemetry进行权限维持
- 无纸化会议转型,做可持续发展企业
- IDEA中如何进行GIT分支合并(转)
- aux ps 和top_关于vmstat,top,ps aux查看的cpu占用率不一致的问题
- 天哪,没有设计经验的ta,居然掌握着“PS大师级
- Xcode4.3.2修改默认公司名称
- 腾讯云开放DevOps敏捷开发套件,助开发者驶入开发快车道
- webmin 远程代码漏洞复现
热门文章
- 雨林木风在东莞倾力打造互联网产业版图
- coffeescript 汉字转拼音代码
- linux centos8 安装jdk 卸载jdk
- python 一球从100m高度落下,一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?Python实例...
- 微信私域流量社群搭建sop流程步骤运营管理方案计划书表格
- 独孤思维:逼迫你赚钱的套路
- 安卓快手跳一跳辅助v1.0.0
- python中的if和if_else以及if_elif_else
- RocketMQ原理
- JavaScript 节点及层级操作