-XX:HeapDumpPath=./java_pid.hprof 指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError 当首次遭遇OOM时导出此时堆中相关信息
-XX:OnError=“;” 出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError=“;” 当首次遭遇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™ 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™ 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问题,会导致所有业务线程卡死!
所以什么时间生成堆文件呢!
java -jar -Xms200m -Xmx200M -XX:+PrintGC -XX:-UseParallelGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/root/springbootgc.hprof ./gc-1.0.jar
-XX:+HeapDumpOnOutOfMemoryError JVM由于内存不足宕机的时候,自动生成
-XX:HeapDumpPath=/root/springbootgc.hprof 堆文件的存储位置
发生死锁的调优场景
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-PlNd5YDo-1712972352321)]
[外链图片转存中…(img-i4DFDoo3-1712972352321)]
[外链图片转存中…(img-rau2AFbb-1712972352322)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-v0qGzyJL-1712972352322)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!