3. 堆空间不够如果应用程序需要的内存比我们执行的Xmx还要大 , 也会导致频繁的垃圾回收 , 甚至OOM 。由于堆空间不足 , 对象分配失败 , JVM就需要调用GC尝试回收已经分配的空间 , 但是GC并不能释放更多的空间 , 从而又回导致GC , 进入恶性循环 。
应用运行时 , 频繁的FullGC会引起长时间停顿 , 在下面这个例子中 , Perm空间几乎是满的 , 并且在Perm区尝试分配内存也都失败了 , 从而触发FullGC:

文章插图
同样的 , 如果在老年代的空间不够的话 , 也会导致频繁FullGC , 这类问题比较好办 , 给足老年代和永久代 , 不要做太抠门的人了 , 嘿嘿 。
4. JVM Bug什么软件都有BUG , JVM也不例外 。有时候 , GC的长时间停顿就有可能是BUG引起的 。例如 , 下面列举的这些JVM的BUG , 就可能导致Java应用在GC时长时间停顿 。

文章插图
如果你的JDK正好是上面这些版本 , 强烈建议升级到更新BUG已经修复的版本 。
5. 显示System.gc调用检查是否有显示的System.gc调用 , 应用中的一些类里 , 或者第三方模块中调用System.gc调用从而触发STW的FullGC , 也可能会引起非常长时间的停顿 。如下GC日志所示 , Full GC后面的(System)表示它是由调用System.GC触发的FullGC , 并且耗时5.75秒:

文章插图
如果你使用了RMI , 能观察到固定时间间隔的FullGC , 也是由于RMI的实现调用了System.gc 。这个时间间隔可以通过系统属性配置:

文章插图
JDK 1.4.2和5.0的默认值是60000毫秒 , 即1分钟;JDK6以及以后的版本 , 默认值是3600000毫秒 , 即1个小时 。如果你要关闭通过调用System.gc()触发FullGC , 配置JVM参数 -XX:+DisableExplicitGC即可 。
那么如何定位并解决这类问题问题呢?
- 配置JVM参数:-XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps and -XX:+PrintGCApplicationStoppedTime. 如果是CMS , 还需要添加-XX:PrintFLSStatistics=2 , 然后收集GC日志 。因为GC日志能告诉我们GC频率 , 是否长时间停顿等重要信息 。
- 使用vmstat, iostat, netstat和mpstat等工具监控系统全方位健康状况 。
- 使用GCHisto工具可视化分析GC日志 , 弄明白消耗了很长时间的GC , 以及这些GC的出现是否有一定的规律 。
- 尝试从GC日志中能否找出一下JVM堆碎片化的表征 。
- 监控指定应用的堆大小是否足够 。
- 检查你运行的JVM版本 , 是否有与长时间停顿相关的BUG , 然后升级到修复问题的最新JDK 。
【一些长时间GC停顿问题的排查及解决办法】
推荐阅读
- 花洒关了为什么会滴一些水,花洒关了还滴水解决小妙招
- 眼睛周围为什么总会有一些小颗粒?
- 玄学为什么能预测未来 一些封建迷信的东西以科学预测学
- 小麦饼的做法
- 常饮苦荞茶 既控三高又美容颜
- 5种吃了就不饿的食物,长时间保持饱腹感才是减肥的背后秘密
- linux 服务器性能分析及优化的一些方法
- 新家具多长时间能入住,新家具有味用什么办法去味
- 甘精胰岛素用量是多少
- 豬膏酒的功效与作用
