我们继承了一个在生产环境中运行的系统,最近开始每 10 小时出现一次故障。基本上,如果系统在一分钟内没有响应,我们的内部软件就会将系统标记为出现故障。我们发现我们的问题是我们的 Full GC 周期持续 1.5 分钟,我们使用 30 GB 堆。现在的问题是我们不能在短时间内优化很多,我们不能快速划分我们的服务,但我们需要尽快摆脱 1.5 分钟的暂停,因为我们的系统由于这些生产暂停而出现故障。对于我们来说,可接受的延迟是 20 毫秒,但不能超过。调整系统的最快方法是什么?减少堆以频繁触发 GC?使用 System.gc() 提示?还有其他解决方案吗?我们使用 Java 8 默认设置,我们有越来越多的用户 - 即创建了越来越多的对象。
一些GC统计
最佳答案
您有很多保留数据。有几个选项值得考虑。
- 将堆增加到 32 GB,如果您有可用内存,这影响不大。再次查看您的总数,您似乎使用了 32 GB 而不是 30 GB,因此这可能没有帮助。
- 如果您没有足够的可用内存,则可能会交换一小部分堆,因为这会显着增加完整的 GC 时间。
- 可能有一些简单的方法可以使数据结构更紧凑。例如使用紧凑的字符串,使用原语而不是包装器,例如
long
用于时间戳而不是Date
或LocalDateTime
。 (长
大约是大小的 1/8) - 如果这些都没有帮助,请尝试将一些数据移出堆。例如Chronicle Map 是一个 ConcurrentMap,它使用堆外内存可以显着减少 GC 时间。也就是说,存储在堆外的数据没有 GC 开销。添加高度的难易程度取决于您的数据结构。
我建议分析您的数据的结构,看看是否有任何简单的方法可以提高数据的效率。
关于java - 如何处理 Java 中较长的 Full Garbage Collection 周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55938677/