参考原文:https://www.zhihu.com/question/427461208/answer/2537026920
可以打印一些当前jvm的各种参数,比如jvm的一些启动参数,jvm中的一些属性k-v等,可以通过 jinfo --help查看具体的命令。
这个参数可以查看JVM内存的一些相关数据;
通过jps获取java进程的PID,通过jmap分析当前java进程的内存数据,常用命令:
jmap -histo[:live] <pid> [ > ./xx.log] : 可以看到当前JVM中所有已加载内的类创建对象的数量,占用内存等,可以导入文件中查看;jmap -heap <pid> :可以查看java程序新生代和老年代的占比即使用情况。jmap -dump:format=b,file=xx.hprof <pid> : 可以dump堆日志,看到的和jmap类似,可以使用visualVM查看。通过jmap可以查看堆的使用情况,比如定位简单的内存泄漏,通过1,3可以看到那些类的对象比较多。
可以设置参数控制发生内存溢出时记录xx.hprof日志,此可以用于分析内存泄漏。-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=xxx/xxx/xx.hprof
这个命令可以查看线程的堆栈信息,jstack可以定位到简单的死锁,常用的是通过jstack定位CPU高的问题,具体步骤是:
top 命令查看当前占用cpu最高的进程pid;top -p <pid> 查看占用内存高的cpu的进程,按 H 来获取当前进程中占用cpu最高的线程的tid;jstack <pid> | grep -A10 <16进制tid> 查看占用线程最高的线程正在执行的具体类信息。注意:tid的16进制要小写。通过这个流程可以直接定位到哪个线程正在执行占用了大量的cpu,包括执行哪个类,非常方便,这个面试经常问。
这个命令可以查看堆的各个部分的详细的使用情况,可以通过jstat --help查看帮助;
最常用的命令jstat -gc <pid> [1000 10]表示查看gc情况,每1秒打印一次总共打印10次(可选),可以查看各个带的使用总大小和使用大小,关键还可以看youngGC,和FullGC各自总次数,总耗时以及一起的耗时等,对于jvm的优化就是要去优化它的FullGC次数,FullGC越少越好,最好控制在FullGC几个小时甚至几天一次,具体看业务的情况。
FullGC频繁分析流程:
FullGC的频繁发生我们不能直接去猜为什么,需要通过一定的分析,去判断是什么原因导致的,一般我们需要用到上面的命令定时去观察堆的情况。
构建模型:
系统所有线程每秒会产生多少M的对象 ==> ①进入Eden;②大对象进入老年代? ==> n秒占满Eden区 ==> 进行youngGC ==> ①进入老年代对象个数(产生原因,动态年龄判断机制?已达到年龄阈值?) ==> FullGC后剩余对象个数
分析问题:
触发FullGC的原因是老年代装不下了,所以需要看老年代为什会频繁的放入对象。。。