Java进阶(JVM调优)——JVM调优参数 & JDK自带工具使用 & 内存溢出和死锁问题案例 & GC垃圾回收_jdk jvm工具使用

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

调优,都必须根据业务场景来调优,不能假设,假设式的调优都是耍流氓!

JVM调优参数

调优参数:java -X & java -XX 开头的这些非标准参数!

主要是java -XX开头的参数,但是没有文档信息介绍

在这里插入图片描述

[root@iZuf61wy7p4tbr7lmwv18iZ ~]# java -X
    -Xmixed           混合模式执行(默认)
    -Xint             仅解释模式执行
    -Xbootclasspath:<用 : 分隔的目录和 zip/jar 文件>
                      设置引导类和资源的搜索路径
    -Xbootclasspath/a:<用 : 分隔的目录和 zip/jar 文件>
                      附加在引导类路径末尾
    -Xbootclasspath/p:<用 : 分隔的目录和 zip/jar 文件>
                      置于引导类路径之前
    -Xdiag            显示附加诊断消息
    -Xnoclassgc        禁用类垃圾收集
    -Xincgc           启用增量垃圾收集
    -Xloggc:<file>    将 GC 状态记录在文件中(带时间戳)
    -Xbatch           禁用后台编译
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xss<size>        设置 Java 线程堆栈大小
    -Xprof            输出 cpu 分析数据
    -Xfuture          启用最严格的检查,预计会成为将来的默认值
    -Xrs              减少 Java/VM 对操作系统信号的使用(请参阅文档)
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xshare:off       不尝试使用共享类数据
    -Xshare:auto      在可能的情况下使用共享类数据(默认)
    -Xshare:on        要求使用共享类数据,否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:system
                      (仅限 Linux)显示系统或容器
                      配置并继续
    -XshowSettings:all
                      显示所有设置并继续
    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
    -XshowSettings:properties
                      显示所有属性设置并继续
    -XshowSettings:locale
                      显示所有与区域设置相关的设置并继续

-X 选项是非标准选项。如有更改,恕不另行通知。

-XX参数主要有3种:行为参数,调优参数,调试参数

行为参数(功能开关)
-XX:-DisableExplicitGC 禁止调用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit 最大化文件描述符的数量限制
-XX:+ScavengeBeforeFullGC  新生代GC优先于Full GC执行
-XX:+UseGCOverheadLimit 在抛出OOM之前限制jvm耗费在GC上的时间比例
-XX:-UseConcMarkSweepGC 对老年代采用并发标记交换算法进行GC
-XX:-UseParallelGC 启用并行GC
-XX:-UseParallelOldGC  对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用
-XX:-UseSerialGC  启用串行GC
-XX:+UseThreadPriorities  启用本地线程优先级
    
性能调优
-XX:LargePageSizeInBytes=4m 设置用于Java堆的大页面尺寸
-XX:MaxHeapFreeRatio=70 GC后java堆中空闲量占的最大比例
-XX:MaxNewSize=size 新生成对象能占用内存的最大值
-XX:MaxPermSize=64m 老年代对象能占用内存的最大值
-XX:MinHeapFreeRatio=40 GC后java堆中空闲量占的最小比例
-XX:NewRatio=2 新生代内存容量与老生代内存容量的比例
-XX:NewSize=size 新生代对象生成时占用内存的默认值
-XX:ReservedCodeCacheSize=32m  保留代码占用的内存容量
-XX:ThreadStackSize=512 设置线程栈大小,若为0则使用系统默认值
-XX:+UseLargePages 使用大页面内存
    
调试参数
-XX:-CITime 打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid<pid>.log 保存错误日志或者数据到文件中
-XX:-ExtendedDTraceProbes  开启solaris特有的dtrace探针
-XX:HeapDumpPath=./java_pid<pid>.hprof 指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError 当首次遭遇OOM时导出此时堆中相关信息
-XX:OnError="<cmd args>;<cmd args>" 出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError="<cmd args>;<cmd args>" 当首次遭遇OOM时执行自定义命令
-XX:-PrintClassHistogram  遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同
-XX:-PrintConcurrentLocks  遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同
-XX:-PrintCommandLineFlags 打印在命令行中出现过的标记
-XX:-PrintCompilation  当一个方法被编译时打印相关信息
-XX:-PrintGC  每次GC时打印相关信息
-XX:-PrintGCDetails  每次GC时打印详细信息
-XX:-PrintGCTimeStamps 打印每次GC的时间戳
-XX:-TraceClassLoading 跟踪类的加载信息
-XX:-TraceClassLoadingPreorder 跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution  跟踪常量池
-XX:-TraceClassUnloading  跟踪类的卸载信息
-XX:-TraceLoaderConstraints 跟踪类加载器约束的相关信息

可以参考:https://blog.csdn.net/geejkse_seff/article/details/124288313

java -jar -XX:+UseG1GC -Xms200m -Xmx200m -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:G1HeapRegionSize=16m -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=5 -XX:G1MaxNewSizePercent=40 -XX:TargetSurvivorRatio=50 -XX:MaxTenuringThreshold=15 -XX:InitiatingHeapOccupancyPercent=45 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/gc.log gc-1.0.jar

使用jdk自带的工具分析

通过DOS命令窗口,启动jar包

java -jar -Xms200m -Xmx200M -XX:+PrintGC -XX:-UseParallelGC gc-1.0.jar

jconsole.exe

在这里插入图片描述

选择不安全连接

在这里插入图片描述

查看VM概要,有启动时设置的参数

在这里插入图片描述

查看控制台概览,堆内存不断增加

在这里插入图片描述

年轻代的gc回收

在这里插入图片描述

可以手动GC

在这里插入图片描述

jvisualvm.exe

另外一个工具 jvisualvm.exe

在这里插入图片描述

能够监测到死锁的产生

在这里插入图片描述

生成dump文件查看

在这里插入图片描述

控制台进行各种GC

在这里插入图片描述

垃圾回收

在这里插入图片描述

开始出现Full GC

在这里插入图片描述

此时,jvm只在回收垃圾

在这里插入图片描述

内存溢出的调优场景

在这里插入图片描述

在Linux系统上运行:

java -jar -Xms200m -Xmx200M -XX:+PrintGC -XX:-UseParallelGC ./gc-1.0.jar

top、 jps 、jinfo、jstat 、jmap

另开一个窗口,去使用上述的命令:

内存溢出在实际的生产环境中经常会遇到,比如,不断的将数据写入到一个集合中,出现了死循环,读取超大的文件等等,都可能会造成内存溢出。如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并且进行分析,是正常还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果是非正常需求,那么就要对代码进行修改,修复这个bug。首先,我们得先学会如何定位问题,然后再进行分析。

在这里插入图片描述

cpu飙升

在这里插入图片描述

top命令发现是java

在这里插入图片描述

jps 查看java进程

jps

在这里插入图片描述

jinfo 63205 查看JVM参数配置

jinfo 63205 查看参数配置

在这里插入图片描述

[root@192 ~]# jinfo 63205
Attaching to process ID 63205, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.371-b11
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.371-b11
sun.boot.library.path = /root/software/jdk/jdk1.8.0\_371/jre/lib/amd64
java.protocol.handler.pkgs = org.springframework.boot.loader
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN\_STANDARD
user.country = CN
user.dir = /usr/local/software/jar/java-gc-demo
java.vm.specification.name = Java Virtual Machine Specification
PID = 63205
java.runtime.version = 1.8.0\_371-b11
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /root/software/jdk/jdk1.8.0\_371/jre/lib/endorsed
line.separator = 

java.io.tmpdir = /tmp
java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
spring.beaninfo.ignore = true
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.10.0-1160.95.1.el7.x86_64
user.home = /root
user.timezone = Asia/Shanghai
catalina.useNaming = false
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
catalina.home = /tmp/tomcat.10050.2643101067280109420
user.name = root
java.class.path = target/spring-gc-demo-1.0-SNAPSHOT.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = target/spring-gc-demo-1.0-SNAPSHOT.jar
java.home = /root/software/jdk/jdk1.8.0\_371/jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0\_371
java.ext.dirs = /root/software/jdk/jdk1.8.0\_371/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /root/software/jdk/jdk1.8.0\_371/jre/lib/resources.jar:/root/software/jdk/jdk1.8.0\_371/jre/lib/rt.jar:/root/software/jdk/jdk1.8.0\_371/jre/lib/jsse.jar:/root/software/jdk/jdk1.8.0\_371/jre/lib/jce.jar:/root/software/jdk/jdk1.8.0\_371/jre/lib/charsets.jar:/root/software/jdk/jdk1.8.0\_371/jre/lib/jfr.jar:/root/software/jdk/jdk1.8.0\_371/jre/classes
java.awt.headless = true
java.vendor = Oracle Corporation
catalina.base = /tmp/tomcat.10050.2643101067280109420
java.specification.maintenance.version = 4
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.cpu.isalist = 

VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:MaxNewSize=69730304 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=69730304 -XX:OldSize=139984896 -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Xms200m -Xmx200M -XX:+PrintGC


发现参数 -Xms200m -Xmx200M -XX:+PrintGC似乎并没有不合理的设置

jstat 查看java进程内存分配

jstat -gc 63205

在这里插入图片描述

  • S0C: 年轻代中第一个survivor(幸存区)的容量(字节)
  • S1C: 年轻代中第二个survivor(幸存区)的容量(字节)
  • S0U: 年轻代中第一个survivor(幸存区)目前已使用空间(字节)
  • S1U: 年轻代中第二个survivor(幸存区)目前已使用空间(字节)
  • EC: 年轻代中Eden(伊甸园)的容量(字节)
  • EU: 年轻代中Eden(伊甸园)目前已使用空间(字节)
  • OC: Old代的容量(字节)
  • OU: Od代目前已使用空间(字节)
  • MC: metaspace(元空间)的容量(字节)
  • MU: metaspace(元空间)目前己使用空间(字节)
  • YGC:从应用程序启动到采样时年轻代中gC次数
  • YGCT: 从应用程序启动到采样时年轻代中gC所用时间(S)
  • FGC:从应用程序启动到采样时old代(全gc) gc次数
  • FGCT:从应用程序启动到采样时old代(全gc) gc所用时间(s)
  • GCT:从应用程序启动到采样时gc用的总时间(s)

jstack 打印出进程内部栈的调用链信息

jstack 63205

在这里插入图片描述

top -p 29046 -H 打印出进程内部线程的CPU占用情况

top -p 63205 -H

在这里插入图片描述

jmap -histo 查看进程中的类,以及类的实例个数

jmap -histo 4498 | head -20 #查看前20条信息

 jmap -histo 63205 | head -20

在这里插入图片描述

剩余的工作:去调整你的业务代码,但是jmap的缺陷在于:它在导出内存图的时候,会STW,所以需要少用!

最好在测试环境中去 复盘出 生产环境的问题;然后在测试机上去使用jmap命令!

 jmap -dump:format=b,file=/root/dump4498.hprof 4498 #将进程中的堆的所有信息快照出来

导出快照仍旧会导致STW问题,会导致所有业务线程卡死!

所以什么时间生成堆文件呢!

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

最好在测试环境中去 复盘出 生产环境的问题;然后在测试机上去使用jmap命令!

 jmap -dump:format=b,file=/root/dump4498.hprof 4498 #将进程中的堆的所有信息快照出来

导出快照仍旧会导致STW问题,会导致所有业务线程卡死!

所以什么时间生成堆文件呢!

[外链图片转存中…(img-0aiatfOD-1715791990176)]
[外链图片转存中…(img-9LOnaRuM-1715791990176)]
[外链图片转存中…(img-KdE97p3B-1715791990176)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值