原文地址:https://mp.weixin.qq.com/s/fP--JJnkTR92NWdZtdEgqQ
作者:阿飞的博客
文章插图
对于许多企业级应用 , 尤其是OLTP应用来说 , 长暂停很可能导致服务超时 , 而对这些运行在JVM上的应用来说 , 垃圾回收(GC)可能是长暂停最主要的原因 。本文将描述一些可能碰到GC长暂停的不同场景 , 以及说明我们如何排查和解决这些GC停顿的问题 。
下面是一些应用在运行时 , 可能导致GC长暂停的不同场景 。
1. 碎片化这个绝对要排在第一位 。因为 , 正是因为碎片化问题--CMS最致命的缺陷 , 导致这个统治了OLAP系统十多年的垃圾回收器直接退出历史舞台(CMS已经是deprecated , 未来版本会被移除 , 请珍惜那些配置了CMS的JVM吧) , 面对G1以及最新的ZGC , 天生残(碎)缺(片)的CMS毫无还手之力 。
对于CMS , 由于老年代的碎片化问题 , 在YGC时可能碰到晋升失败(promotion failures , 即使老年代还有足够多有效的空间 , 但是仍然可能导致分配失败 , 因为没有足够连续的空间) , 从而触发Concurrent Mode Failure , 发生会完全STW的FullGC 。FullGC相比CMS这种并发模式的GC需要更长的停顿时间才能完成垃圾回收工作 , 这绝对是JAVA应用最大的灾难之一 。
为什么CMS场景下会有碎片化问题?由于CMS在老年代回收时 , 采用的是标记清理(Mark-Sweep)算法 , 它在垃圾回收时并不会压缩堆 , 日积月累 , 导致老年代的碎片化问题会越来越严重 , 直到发生单线程的Mark-Sweep-Compact GC , 即FullGC , 会完全STW 。如果堆比较大的话 , STW的时间可能需要好几秒 , 甚至十多秒 , 几十秒都有可能 。
接下来的cms gc日志 , 由于碎片率非常高 , 从而导致promotion failure , 然后发生concurrent mode failure , 触发的FullGC总计花了17.1365396秒才完成:
文章插图
文章插图
文章插图
2. GC时操作系统的活动当发生GC时 , 一些操作系统的活动 , 比如swap , 可能导致GC停顿时间更长 , 这些停顿可能是几秒 , 甚至几十秒级别 。
如果你的系统配置了允许使用swap空间 , 操作系统可能把JVM进程的非活动内存页移到swap空间 , 从而释放内存给当前活动进程(可能是操作系统上其他进程 , 取决于系统调度) 。SwApping由于需要访问磁盘 , 所以相比物理内存 , 它的速度慢的令人发指 。所以 , 如果在GC的时候 , 系统正好需要执行Swapping , 那么GC停顿的时间一定会非常非常非常恐怖 。
下面是一段持续了29.48秒的YGC日志:
文章插图
最后一行[Times: user=915.56, sys=6.35, real=29.48 secs]中real就是YGC时应用真实的停顿时间 。发生YGC的这个时间点 , vmstat命令输出结果如下:
文章插图
YGC总计花了29秒才完成 。vmstat命令输出结果表示 , 可用swap空间在这个时间段减少了600m 。这就意味着 , 在GC的时候 , 内存中的一些页被移到了swap空间 , 这个内存页不一定属于JVM进程 , 可能是其他操作系统上的其他进程 。
从上面可以看出 , 操作系统上可用物理内容不足以运行系统上所有的进程 , 解决办法就是尽可能运行更少的进程 , 增加RAM从而提升系统的物理内存 。在这个例子中 , Old区有9G , 但是只使用了1.8G(mark-sweep generation total 9437184K, used 1860619K) 。我们可以适当的降低Old区的大小以及整个堆的大小 , 从而减少内存压力 , 最小化系统上的应用发生swapping的可能 。
除了swapping以外 , 我们也需要监控了解长GC暂停时的任何IO或者网络活动情况等, 可以通过IOStat和netstat两个工具来实现. 我们还能通过mpstat查看CPU统计信息 , 从而弄清楚在GC的时候是否有足够的CPU资源 。
推荐阅读
- 花洒关了为什么会滴一些水,花洒关了还滴水解决小妙招
- 眼睛周围为什么总会有一些小颗粒?
- 玄学为什么能预测未来 一些封建迷信的东西以科学预测学
- 小麦饼的做法
- 常饮苦荞茶 既控三高又美容颜
- 5种吃了就不饿的食物,长时间保持饱腹感才是减肥的背后秘密
- linux 服务器性能分析及优化的一些方法
- 新家具多长时间能入住,新家具有味用什么办法去味
- 甘精胰岛素用量是多少
- 豬膏酒的功效与作用