什么情况下回触犯FullGC
- 使用了大对象 //大对象会直接进入老年代
- 在程序中长期持有了对象的引用 //对象年龄达到指定阈值也会进入老年代
- JVM内存设置不合理
FullGC出现的表象
- CPU飙升或忽高忽低;
- 程序性能不问题,接口响应时间比较长。
如何判断FullGC
- 通过监控工具或告警,如Prometheus
- 通过jstat指令
可以通过ps -ef|grep java
或者jsp
获得java进程号,下面实例中java进程号就是56。
jps
71 Jps
56 DemoApplication
通过jstat -gc 56 5000
即会每5秒一次显示进程号为56的java进成的GC情况,FGC、FGCT分别代表FullGC次数和时间,来初步判断是否为FullGC。
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 0.0 0.0 15872.0 13251.7 42496.0 488.1 4864.0 3526.0 512.0 380.5 7 0.016 0 0.000 0.016
512.0 1024.0 0.0 0.0 15872.0 11066.6 42496.0 488.1 4864.0 3526.0 512.0 380.5 8 0.018 0 0.000 0.018
1024.0 1024.0 0.0 0.0 15872.0 7599.2 42496.0 488.1 4864.0 3526.0 512.0 380.5 9 0.019 0 0.000 0.019
如何定位内存问题导致FullGC
一个解决房方案是,在其中一台机子上开启- XX:HeapDumpBeforeFullGC
另一个就是dump出来文件。
jmap -dump:format=b,file=/my.dump 56
导出56进程的java程序的整个JVM信息。
jmap -dump:format=b,file=/my.dump 56
Dumping heap to /my.dump ...
Heap dump file created
再通过MAT、VisualVM等工具导入查看。如果手头没有这样的工具,可以试试通过下面指令简单看看。
jmap -heap 56
查看进程号为56的Java程序的整个jvm内存状态
jmap -histo 56
查找进程号为56的java程序的jvm堆中对象详细占用情况
jhat -port 9998 /tmp/dump.dat
Reading from /tmp/dump.dat...
Dump file created Tue Jan 28 17:46:14 CST 2014
Snapshot read, resolving...
Resolving 132207 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 9998
Server is ready.
然后就可以在浏览器中输入主机地址:9998查看了。
参考:
- jvm调优监控工具jps、jstack、jmap、jhat、jstat使用详解