当前位置:首页 > Java技术 > 记录一次jvm调优过程

记录一次jvm调优过程

2022年09月16日 22:54:46Java技术10

1.查看gc情况:
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
结果:服务启动时长是1天,进行了3240左右次minorGC,一共使用时间80s左右。也就是一次minirGC时间是0.02s,FGC是一次,时间是2.2s,fullGC时间过长,需要优化。
1.为什么需要优化:
FGC会不会导致请求失败?
1.1查看GC方式是什么:
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
新生代使用的是PS Young Generation回收器,也就是Parallel Scavenge回收器,特点是使用复制算法的多线程serial回收器,跟perNew区别是更注重程序的吞吐量,吞吐量是要尽量保证系统运行时间,减少垃圾回收时间。在回收时会暂停所有的用户线程。老年代使用的是PS Old Generation回收器,也就是Parallel Scavenge的年老代版本,使用的是标记整理算法。其他特点见新生代。
几个名词的解释:
吞吐量与收集器关注点说明
(A)、吞吐量(Throughput)
CPU用于运行用户代码的时间与CPU总消耗时间的比值;
即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间);
高吞吐量即减少垃圾收集时间,让用户代码获得更长的运行时间;
(B)、垃圾收集器期望的目标(关注点)
(1)、停顿时间
停顿时间越短就适合需要与用户交互的程序;
良好的响应速度能提升用户体验;
(2)、吞吐量
高吞吐量则可以高效率地利用CPU时间,尽快完成运算的任务;
主要适合在后台计算而不需要太多交互的任务;
(3)、覆盖区(Footprint)
在达到前面两个目标的情况下,尽量减少堆的内存空间;
可以获得更好的空间局部性;
通过分析GC回收器可以知道在GC回收时会暂停用户线程,可能会造成短暂的系统不可用。而且我们系统是更注重用户体验的系统,应该更加关注垃圾回收的时间而不是系统吞吐量,
优化思路:1.新生代回收时间较短不需要优化
2.老年代使用cms回收器或G1回收器
-XX:+UseConcMarkSweepGC :启用cms
-XX:ParallelGCThreads=16 :设置垃圾回收时使用的线程数。默认是8,也可以用命令查询:
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
-XX:+CMSScavengeBeforeRemark :强制remark之前开始一次minor gc,减少remark的暂停时间
-XX:+CMSParallelRemarkEnabled :并行remark,减少标记时间
-XX:CMSInitiatingOccupancyFraction :老年代占据多少时进行cms,查看了下默认配置:
java -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal Benchmark | grep "CMSInitiatingOccupancyFraction "
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
竟然是-1,也就是老年代满了的时候再进行cms,暂时不是很确定,但通过日志看像是的:
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记
后来通过查https://blog.csdn.net/foolishandstupid/article/details/77430875得知计算得到_initiating_occupancy=(100-40+80*40/100)/100=92%。也就是说,如果不配置CMSInitiatingOccupancyFraction参数,默认情况下,initiating_occupancy的值就是92%。这种情况是很危险的。有可能导致cms失败:Prommotion failed和Concurrent mode failed。
Prommotion failed:这个问题的产生是由于救助空间不够,从而向年老代转移对象,年老代没有足够的空间来容纳这些对象,导致一次full gc的产生。解决这个问题的办法有两种完全相反的倾向:增大救助空间、增大年老代或者去掉救助空间。 增大救助空间就是调整-XX:SurvivorRatio参数,这个参数是Eden区和Survivor区的大小比值,默认是32,也就是说Eden区是 Survivor区的32倍大小,要注意Survivo是有两个区的,因此Surivivor其实占整个young genertation的1/34。调小这个参数将增大survivor区,让对象尽量在survitor区呆长一点,减少进入年老代的对象。去掉救助空 间的想法是让大部分不能马上回收的数据尽快进入年老代,加快年老代的回收频率,减少年老代暴涨的可能性,这个是通过将-XX:SurvivorRatio 设置成比较大的值(比如65536)来做到。在我们的应用中,将young generation设置成256M,这个值相对来说比较大了,而救助空间设置成默认大小(1/34),从压测情况来看,没有出现prommotion failed的现象,年轻代比较大,从GC日志来看,minor gc的时间也在5-20毫秒内,还可以接受,因此暂不调整。

Concurrent mode failed的产生是由于CMS回收年老代的速度太慢,导致年老代在CMS完成前就被沾满,引起full gc,避免这个现象的产生就是调小-XX:CMSInitiatingOccupancyFraction参数的值,让CMS更早更频繁的触发,降低年老代被沾满的可能。我们的应用暂时负载比较低,在生产环境上年老代的增长非常缓慢,因此暂时设置此参数为80。在压测环境下,这个参数的表现还可以,没有出现过Concurrent mode failed。
G1回收器:
Eden区和survival区比例是否合理
-XX:+PrintTenuringDistribution让JVM在每次MinorGC后打印出Survivor空间中的对象的年龄分布

综上:jvm参数配置参考:
-server -Xms12288m
-Xmx12288m
-XX:NewRatio=2
-XX:SurvivorRatio=4
-XX:MetaspaceSize=1024m
-XX:MaxMetaspaceSize=1024m
-XX:+UseConcMarkSweepGC
-XX:+CMSScavengeBeforeRemark
-XX:+CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=60
-XX:+UseCompressedClassPointers 压缩类指针
-XX:+UseCompressedOops 压缩对象指针
日志相关:
-XX:+PrintTenuringDistribution让JVM在每次MinorGC后打印出Survivor空间中的对象的年龄分布
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-XX:+PrintFlagsFinal
-Xloggc:/datalog/tomcat-gc.log
运行半个月的情况:
记录一次jvm调优过程 _ JavaClub全栈架构师技术笔记

作者:竹下星空
来源链接:https://blog.csdn.net/shidebin/article/details/106359917

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/42198.html

标签: JVM调优
分享给朋友:

“记录一次jvm调优过程” 的相关文章

深入理解JVM(1)——JVM内存模型

Java虚拟机的内存空间分为五个部分,分别是: 程序计数器; Java虚拟机栈 本地方法栈 堆 方法区 接下来对这五部分分别进行详细的介绍 1、程序计数器:   a)什么是程序计数器:程序计数器是内存中的一个很小...

深入理解JVM—JVM内存模型

深入理解JVM—JVM内存模型

原文地址:http://yhjhappy234.blog.163.com/blog/static/316328322011101723933875/?suggestedreading&wumii 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁...

JVM 算法简介

JVM 算法简介

JVM学习目录 1.JVM 概念简介 2.JVM 运行时内存 3.JVM算法简介 4.JVM 垃圾收集器 5.JVM 调优实战 通过以上的文章我们对JVM有了初步的认识,在前几篇文章中也说过一些算法知识点,今天这篇文章我们进行算法的分享 一、...

jvm-java 内存模型  以及各个分区具体内容

jvm-java 内存模型 以及各个分区具体内容

java内存模型,这里其实是指 jvm运行时内存模型 1 每一个应用程序,都有一个JVM 而不是 多个应用程序,共享一个jvm 2 java源文件,首先通过编译器,把java语法的代码,编译成 jvm语法的字节码文件 这个过程,是不涉及到...

JVM学习笔记——java内存模型

JVM学习笔记——java内存模型

概述 JVM规范希望定义一套java内存模型(java memory model,JMM),使得java程序在不同的硬件平台下面都能展现出一致的内存访问机制。 java内存模型规定所有变量保存在主内存中,每个线程有自己的工作内存。线程的工作内存中保存了该线程使用到的变量的主内存拷...

JVM——Java内存模型(JMM)

JVM——Java内存模型(JMM)

本文主要介绍JVM——Java内存模型(JMM),并介绍原子性、可见性、有序性以及先行发生原则。 软硬件发展概述 Amdahl定律和摩尔定律 1)Amdahl定律:通过系统中并行化和串行化的比重来描述多处理器系统能获得的运算加速能力。 2)摩尔定律:用于描...

一、JVM运行原理之Java内存模型

一、JVM运行原理之Java内存模型

JVM内存模型   对于Java开发者来说,我们不必关注内存的使用和释放问题,而是统一的交由Java虚拟机去统一的管理,这样一方面大大减轻了开发者的负担,同时也降低的开发的门槛,所以现在Java的广泛使用,Java虚拟机功不可没。虽然我们在开发过程中不必关注虚拟机的运行状况,但如...

线上jvm 内存飙高排查

线上jvm 内存飙高排查

1.jps查看java进程的pid 2.使用jmap把内存导出,查看是哪些对象占用内存高 jmap -histo 16352 >f:/dev/histo.txt 3. 使用jmap查看堆内存的使用情况 jmap -heap 16...

JVM参数设置

JVM参数设置

JVM参数设置 基本参数 通过一张图来了解如何通过参数来控制各区域的内存大小 控制参数 -Xms设置堆的最小空间大小。 -Xmx设置堆的最大空间大小。 -XX:NewSize设置新生代最小空间大小。...

二: Jvm内存模型

二: Jvm内存模型

为什么jvm要有内存模型   在  上一章节  我们清楚代码的运行流程之后,那么下面一段代码我们就可以知道: 1. main线程启动,main()方法的栈帧压入main线程的虚拟机栈2. web()方法的栈帧也压入main线程的虚拟机栈3. web()栈...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。