JVM实战调优案例
JVM实战调优案例
- 案例背景
- 机器配置
- 问题发现
- 突破点
- 尝试解决问题
- 建议排查步骤
- 总结
案例背景
应用每次产生Full GC,持续的时间非常长,大概需要20多秒才能完成。那么会产生一个报警,但是一开始只是偶尔一次,我们也没有注意,随着时间越来越长,每周就会产生一次Full GC,时间都是20多秒。这种情况下,我们不得不去解决一下。
机器配置
机器是一个4C 8G的配置,但是老年代分配的内存分配了6G,其他都是中规中矩的操作。通过开启GC日志寻找问题,结合机器的各种指标(CPU、内存、磁盘、线程等等),这些是由监控工具来产生。没有的可以通过普罗米修斯等等一些东西来看。
问题发现
每次只要产生FullGC的时候,CPU有上升,内存有上升,但是内存的SWAP区内存有下降。
【补充】SWAP交换分区:通常被称为交换分区,这是一块特殊的硬盘空间,即当物理内存不够用的时候,操作系统会从物理内存中取出一部分暂时不用的数据,放在交换分区中,从而为当前运行的程序腾出足够的内存空间。
突破点
难道JVM会用到SWAP,SWAP会导致回收缓慢?
具体来看SWAP被程序使用的情况,随着内存的上升,JAVA使用了300多M的SWAP。
OOM发生问题的时候,OCS(开放缓存服务)发现内存不足时,会把内存中暂时不用的数据交换出去,放到SWAP区中。这个过程就称为SWAP-OUT。
当某个进程又需要这个数据,且又发现内存中有的时候,它就会从SWAP区将其交换回来。这个就是内存与SWAP进行交换的一个过程。
尝试解决问题
发现这个问题之后,抽查了所有发生Full GC的机器,都是SWAP区上升,内存下降。那么这时候我们先把SWAP区关掉,尝试下看看会不会产生问题。通过修改操作系统的VM参数去禁用SWAP, 然后再启动测试,发现问题得到解决。
只要我们将SWAP关闭或者释放,那么我们的FullGC立刻进行了一个完完全全的回收而且还非常快。也就是我们所有需要回收的东西都在内存中。这个时候,我们就相当于把内存中的FullGC时间20秒一下降到了100ms。SWAP区不再使用,并且内存也够用。
所以最终FullGC整体时间偏长的问题得到了解决。
【补充】Full GC:指的是针对新生代、老年代、永久代的全体内存空间的垃圾回收,所以称之为Full GC。
建议排查步骤
- 检查应用程序的内存使用情况:确认应用程序是否存在内存泄漏或者内存占用过高的情况。可以通过监控工具或分析堆转储文件(heap dump)来查看内存使用情况和对象分布。
- 检查GC日志:仔细分析GC日志,查看GC事件的频率、持续时间以及GC算法的选择。确定是否存在GC过于频繁或者长时间的GC暂停。
- 检查JVM参数配置:确认JVM参数是否合理配置,特别是与内存相关的参数,如堆大小、新生代和老年代的比例、垃圾回收器的选择等。适当调整这些参数可以改善GC性能。
- 监控系统资源使用情况:使用系统监控工具监视CPU、内存、磁盘和网络等系统资源的使用情况。确定是否存在其他进程或系统服务占用过高的资源。
总结
请注意,关闭Swap区并不是解决高CPU和内存占用的最佳方案。在真实的生产环境中,为了确保系统的稳定性和可靠性,通常建议维持Swap区的开启状态,并通过优化应用程序的内存使用、调整JVM参数和监控系统资源等手段来解决CPU和内存问题。
参考资料:JVM实战调优案例,面试可吹!
还没有评论,来说两句吧...