是否可以在 Java 中更改垃圾收集器的频率?

Is it possible to change the frequency of the garbage collector in Java?

有没有办法改变垃圾收集器的频率,是减少还是增加?

我发现有些文章说为了提高频率,我需要增加新生代,让更多的对象在GC被调用之前进入。

但我没有在任何地方找到真正的方法来做到这一点,使用真正的命令或操作或说明如何实现它(减少或增加 GC 频率)。

您首先配置要使用的垃圾收集器,然后您可以配置所述垃圾收集器。

无论你读到什么,它都是无关紧要的/无效的/具有误导性的/过于简单化了。垃圾收集极其复杂,特别是复杂到谈论 'frequency' 没有任何意义。 20 年前垃圾收集很简单:

  • 冻结每个线程。
  • 列出所有活动对象。
  • 对这些对象进行树遍历以找到从这些活动对象可到达的所有对象,然后继续遍历。
  • 从分配给 JVM 的堆内存中的位置 0 开始,开始移动每个仍可访问的对象,同时更新所有指针,因此静默覆盖所有不可访问的对象。
  • 大功告成;内存非常紧凑,大量可用 space,解冻世界。

那个型号?它在 20 年前就死了。垃圾收集现在要复杂得多,包括以下方面:

  • 实时跟踪:JVM 使用启发式机制能够快速收集一部分垃圾。 (基本上,引用计数;如果引用计数为 0,则肯定是垃圾。但是,非 0 引用计数也可能是垃圾,例如,如果 a 引用 b,b 引用 a,并且没有任何内容 'live' 引用任何一个:两个引用计数都是 1,但它们仍然是垃圾)。这些垃圾收集器仍在收集它们,只是收集速度不如 refcount-0 垃圾。 'frequency' 现在是什么意思?

  • 几代人,几代人之间的方法截然不同。例如,您的基本 eden/'fast garbage' 系统以相反的方式工作:一个 java 线程获得一页内存,新对象在这里创建,任何其他线程都完全无法访问。一旦它满了,系统就会快速检查这个线程当前在上下文中可以访问的内容,并创建一个新页面,只复制仍然可以访问的对象,并将旧页面标记为空闲。 “免费垃圾收集”刚刚发生。 'frequency' 在这里到底是什么意思?无需配置:当页面已满时,此过程开始。直到页面已满,它才不会。无需配置。

这只是垃圾收集器所做的 50 件事中的 2 件事,不能简单地描述为可以明确应用术语 'frequency' 的事情。

每个 JDK 版本都对可用的 GC 实现、这些实现的工作方式,甚至这些实现支持的设置进行了相当大的更改。 None 其中是核心 java 规范的一部分,这意味着 OpenJDK 团队对于在 java 版本之间更改它们更加随意,并且出于同样的原因, Azul、coretto 等备用 JDK 提供程序经常提供额外的 GC impls 和额外的设置。

那我该怎么办?

别担心了。一般的经验法则是:如果你弄乱了 GC 设置,你会让一切变得更糟。如果您需要调整 GC 设置,请咨询专家,并放心,因为您不太可能需要它。

忘掉你阅读的内容。这是过时的信息。