JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是jconsole 和 jvisualvm 这两款视图监控工具。
jconsole:用于对 JVM 中的内存、线程和类等进行监控;
jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等
-Xms2g:初始化推大小为 2g;
-Xmx2g:堆最大内存为 2g;
-XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
-XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组
合;
-XX:+PrintGC:开启打印 gc 信息;
-XX:+PrintGCDetails:打印 gc 详细信息。
首先 针对cpu占用过高,肯定是某个程序长期占用了cpu资源导致的
所以针对这个问题
首先我们要知道,内存飚高如果是发生在 java 进程上,一般是因为创建了大量对象所导致,而如果持续飚高意味着垃圾回收跟不上对象创建的速度,或者内存泄露导致对象无法回收
针对这种情况
1 先打印gc的情况,即通过jstat -gc PID 1000 查看 GC 次数,时间等信息,看看对象的GC 次数是否频繁,而且每次回收的内存空间是否正常,如果说每次回收的内存都很少,GC非常频繁 那么可能是因为内存泄露导致的
2 导出堆内存文件快照
即可以通过 jmap -dump 导出堆内存信息到文件
3 使用 visualVM 对 dump 文件进行离线分析,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题
我们的确遇到过内存泄露,但其实在具体的表现上,可能是先出现以下这几种情况
之后我们还需要通过jstat 命令输出gc的信息,即查看 YGC 和 Full GC 次数。通常会出现 YGC 不增加或增加缓慢,而 Full GC 增加很快。如果发现 Full GC 次数太多,就很大概率存在内存泄漏了,然后可以用 jmap -dump 生成 dump 文件,借助工具分析哪 个对象非常多,基本就能定位到问题在那了