java - 如何处理 Java 中较长的 Full Garbage Collection 周期

标签 java garbage-collection jvm

我们继承了一个在生产环境中运行的系统,最近开始每 10 小时出现一次故障。基本上,如果系统在一分钟内没有响应,我们的内部软件就会将系统标记为出现故障。我们发现我们的问题是我们的 Full GC 周期持续 1.5 分钟,我们使用 30 GB 堆。现在的问题是我们不能在短时间内优化很多,我们不能快速划分我们的服务,但我们需要尽快摆脱 1.5 分钟的暂停,因为我们的系统由于这些生产暂停而出现故障。对于我们来说,可接受的延迟是 20 毫秒,但不能超过。调整系统的最快方法是什么?减少堆以频繁触发 GC?使用 System.gc() 提示?还有其他解决方案吗?我们使用 Java 8 默认设置,我们有越来越多的用户 - 即创建了越来越多的对象。

一些GC统计

enter image description here

最佳答案

您有很多保留数据。有几个选项值得考虑。

  • 将堆增加到 32 GB,如果您有可用内存,这影响不大。再次查看您的总数,您似乎使用了 32 GB 而不是 30 GB,因此这可能没有帮助。
  • 如果您没有足够的可用内存,则可能会交换一小部分堆,因为这会显着增加完整的 GC 时间。
  • 可能有一些简单的方法可以使数据结构更紧凑。例如使用紧凑的字符串,使用原语而不是包装器,例如long 用于时间戳而不是 DateLocalDateTime。 ( 大约是大小的 1/8)
  • 如果这些都没有帮助,请尝试将一些数据移出堆。例如Chronicle Map 是一个 ConcurrentMap,它使用堆外内存可以显着减少 GC 时间。也就是说,存储在堆外的数据没有 GC 开销。添加高度的难易程度取决于您的数据结构。

我建议分析您的数据的结构,看看是否有任何简单的方法可以提高数据的效率。

关于java - 如何处理 Java 中较长的 Full Garbage Collection 周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55938677/

相关文章:

java - 为什么 Java 需要 "This method can be called at most once in a given Java Virtual Machine"?

java - spring boot - 应用程序启动两次..?

java - 人们怎样才能在使用 java applet 进行绘图的同时仍然拥有完整的功能呢?

java - [Android]Google Gson 崩溃应用

c# - 调用Dispose不会清理对象C#使用的内存?

java - "All Java byte code interpreter are JVMs but all JVMs are not Java interpreters"的说法是真的吗?

jvm - 当前的 HotSpot JVM 默认是并行运行的吗?

java - 如何使用 applet 和 servlet 在两个客户端和仅两个客户端之间发起聊天?

java - 如何将 List<List<String[]>> 转换为 String[][][]?

memory-leaks - 垃圾收集器会导致内存泄漏吗?