首页 > 其他分享 >JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优

时间:2023-12-23 10:01:54浏览次数:26  
标签:Full 虚拟机 XX 调优 GC JVM 空间 线程

通过 gceasy工具对生成的 GC 日志进行分析

这里使用的 JDK 版本为 JDK8!

在分析 GC 日志时,可以同时采用多种工具(Arthas、gceasy、JVM 连接 Graphana 监控)进行分析,避免某种工具分析不准确

gceasy 每个月只可以免费分析 5 个 gc 日志,因此要节约机会!hhh!

我们先将 gc.log 文件放入 gceasy 中进行分析,分析结果如下:

首先是 JVM 内存大小,可以看到新生代分配了 624 mb,而 Peak 也就是峰值也达到了 624 mb,说明新生代很容易就被占满了,而对于元空间 Meta Space 来说,分配了 1 个 gb,而峰值才使用了 59 mb,因此元空间分配的大小也不合理,对于 JDK8 来说,如果不指定元空间的大小,默认元空间的最大值是系统内存的大小,在 64 位操作系统中,元空间默认初始值为 21MB,如果初始未给定的元空间的大小,导致初始元空间过小,会 频繁触发 Full GC 来调高元空间大小

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_JVM


接下来看一些关键的性能指标,可以看到 Avg Pause GC Time 也就是平均 GC 时间为 10 ms,最大 GC 时间为 190 ms,这些参数目前看来也正常,没有出现过长的 GC 时间

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_堆栈_02


接下来看一下 GC 持续时间的一些情况,可以看到在系统刚开始就发生了几次 Full GC,这是很严重的问题,可以看到这三次 Full GC 产生的原因分别是:Metadata GC ThreasholdErgonomics,即元空间超过阈值,Ergonomics 的含义是自动调节 GC 暂停时间和吞吐量从而产生的 GC,是虚拟机中对性能的优化,那么因为 Ergonomics 产生的 GC 我们可以不管,总结一下这几次 Full GC 产生的原因就是 元空间超过阈值!

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_老年代_03


最后我们可以看一下 GC 的指标,可以看到 Full GC 总共发生了 6 次,还是比较多的,需要控制一下 Full GC 的次数,因为 Full GC 对系统性能影响是比较大的

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_JVM_04


上边我们已经通过 gceasy 分析了 gc 日志了,存在的问题主要有以下几点:

  • Meta Space 空间分配不合理
  • Full GC 产生次数过多

堆和元空间优化

那么优化参数我们从 堆空间元空间新生代 3 个方面进行入手,参数调整如下:

-Xms1096m -Xmx1096m -Xmn408m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m
  • 堆空间通过 -Xms -Xmx 来进行调整,为了尽量避免 Full GC,堆空间可以设置为 Full GC 后老年代空间占用的 3-4 倍 ,这样的话一般可以避免老年代空间不足从而导致 Full GC 的情况,最好设置为 8 的整数倍,我们通过上边 easygc 分析中的 JVM Memory Size 得知,老年代的峰值为 274mb,因此这里设置堆空间大小为 274 * 4 = 1096 mb,设置堆空间为 Full GC 后老年代对象的 4 倍大小
  • 元空间通过 -XX:MetaspaceSize=N 来设置,这里设置元空间大小为 128 mb
  • 新生代通过 -Xmn 来设置,新生代可以设置为 Full GC 后老年代空间占用的 1-1.5 倍 ,即 274 * 1.5 = 411 mb,最好设置为 8 的整数倍,因此改为 408 mb

可以看到优化后,JVM 内存的使用更加合理了,新生代也没有超过分配的内存大小,如下图:

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_JVM_05

并且 Full GC 的次数为 0

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优_堆栈_06


这里需要注意的是,如果使用 Docker 部署的 java 应用,可以在 Dockerfile 中设置 JVM 的参数,并且在启动的时候,尽量去将 JVM 参数打印出来,确保设置的参数生效!



线程堆栈优化

上边对 JVM 中的堆和方法区的大小进行了优化,接下来看一下如何对 JVM 中的线程堆栈进行优化

JDK5.0 后每个线程堆栈大小为 1M,在相同物理内存下,线程堆栈越小,就能生成更多的线程,但是操作系统对一个进程内的线程数量还是有限制的,如果堆栈不是很深可以设置 256k,如果是很大的应用可以使用 512k

对于平常的系统来说,是不需要进行线程堆栈的优化的,但是如果开发一些中间件的话,需要创建出很多的线程,那么对于线程堆栈的优化还是比较有必要的,线程堆栈大小设置通过 -Xss 进行设置

-Xms1096m -Xmx1096m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xss512k


垃圾回收器组合优化

  • 吞吐量优先:Parallel Scavenge + ParallelOldGC
  • 响应时间优先(低延迟):ParNew + CMS

G1 垃圾回收器

G1 兼顾了吞吐量和响应时间,尤其在大内存的情况下比较好,配置 G1 只需要 3 步:

  1. 开启 G1 垃圾收集器
  2. 设置堆内存
  3. 设置最大的停顿时间
# 设置堆、元空间大小
 -Xms256m -Xmx256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xss512k
 # 开启 G1
 -XX:+UseG1GC -XX:MaxGCPauseMillis=100
  # 开启 GC 日志创建更详细的 GC 日志
 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps,-XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:./logs/gc.log


标签:Full,虚拟机,XX,调优,GC,JVM,空间,线程
From: https://blog.51cto.com/u_16186397/8944648

相关文章

  • JVM虚拟机系统性学习-JVM调优之GC日志分析
    JVM调优首先,为什么要JVM调优呢?JVM调优的目的就是为了让应用程序使用最小的硬件消耗来承载更大的吞吐量什么情况下需要JVM调优呢?系统吞吐量下降,或系统延迟较高出现OOMFullGC频繁GC停顿时间过长(超过1s,已经影响用户体验)调优主要调什么?JVM调优主要是两方面:内存分配和垃圾回......
  • Java JVM面试题
    我分析了上百份大中小厂的面经,整理了Java面试中最最最常问的一些问题!小伙伴们可以对照着网站里面的文章学习或者准备面试。网站的内容会继续完善,欢迎你在评论区说出你遇到的高频面试题!林老师带你学编程(「Java学习+面试指南」是一份涵盖大部分Java程序员所需要掌握的核心知识......
  • 1. JVM
    JVMJVM(JavaVirtualMachine)是一种能够执行Java字节码的虚拟机,是实现Java跨平台特性的核心部分,他屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在JVM上运行的目标代码(字节码),就可以在多种平台上不加修改地运行JDK、JRE与JVMJDK(JavaDevelopmentKit):Java......
  • JVM基础篇(三)-JVM结构-运行时数据区之栈帧
    栈帧栈帧的内部结构每个栈帧中存储着:局部变量表(LocalVariables)操作数栈(operandStack)(或表达式栈)动态链接(DynamicLinking)(或指向运行时常量池的方法引用)方法返回地址(ReturnAddress)(或方法正常退出或者异常退出的定义)一些附加信息并行每个线程下的栈都是私有的,因此每个线程都有自己各......
  • java中对于jvm虚拟机进程的操作类
    在java中,Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。下面图示演示了其方法以及应用。......
  • JVM实战-G1参数调优
    G1简介G1GC,全称Garbage-FirstGarbageCollector,在JDK1.7中引入了G1GC,从JAVA9开始,G1GC是默认的GC算法。通过-XX:+UseG1GC参数来启用。G1收集器有分区概念,是工作在堆内不同分区上的收集器。G1的分区既可以是年轻代也可以是老年代,同一个代的分区不需要连续。G1收集器在运行过......
  • JVM内存参数的学习之三
    JVM内存参数的学习之三背景研究启动性能时,顺便看到了jmap-heap1的部分信息看到:MinHeapFreeRatio、MaxHeapFreeRatio自己突然以为是Percentage的参数,恍惚了好久.才发现自己对内存的学习不够,所以想多学习一下.参数解释MinHeapFreeRatio:空闲堆空间的最小......
  • nginx调优-调大rlimit_nofile
    前言对于Linux用户或用户组打开的进程,Linux系统会对进程可占用的资源进行限制。该限制针对特定Linux用户或用户组,限制范围是该Linux用户或用户组打开的所有进程。遇到的异常nginx转发的流量比较大。因此在nginx.conf中,存在如下配置:worker_rlimit_nofile131072;event{......
  • JVM虚拟机系统性学习-JVM相关工具jps、jstat、jinfo、jmap、jhat和jstack
    JVM相关工具JDK工具包jps查看Java进程jps:列出Java程序进程ID和Main函数名称jps-q:只输出进程IDjps-m:输出传递给Java进程(主函数)的参数jps-l:输出主函数的完整路径jps-v:显示传递给Java虚拟机的参数jstat查看Java程序运行时相关信息,可以查看运行时堆的相关情况jstat......
  • 记录一次两台电脑vmware中的虚拟机互相访问学习经过
    装过VMware的都知道,VMware有四种网络选择,桥接,主机,和nat,平时都是会使用vmnet8作为网络。因为桥接会使用和宿主机同一个网络,估计会在路由器中注册自己的ip地址。nat模式是网关和dhcp服务交给了虚拟的一个VMnet8网卡,网卡接口为.1出现在宿主机路由表,.2的网关,dhcp随机找一个网段和范围,......