Java中垃圾回收的频率是多少?

2022-09-03 14:19:37

文档 Java HotSpot™ 虚拟机中的内存管理的第 6 页包含以下段落:

年轻一代集合发生得相对频繁,并且高效且快速,因为年轻一代空间通常很小,并且可能包含许多不再引用的对象。

在一些年轻一代收藏中幸存下来的物品最终会被提升或终身保有给老一代。参见图1。这一代人通常比年轻一代大,其占用率增长较慢。因此,老一代馆藏很少见,但需要更长的时间才能完成。

有人可以在上面的陈述中定义“频繁”和“不频繁”的含义吗?我们是在谈论微秒,毫秒,分钟,天吗?


答案 1

对此不可能给出明确的答案。这实际上取决于很多因素,包括平台(JVM版本,设置等),应用程序和工作负载。

在一个极端情况下,应用程序可能永远不会触发垃圾回收器。它可能只是坐在那里不做任何事情,或者它可能执行一个非常长的计算,其中在JVM初始化和应用程序启动后不创建任何对象。

在另一个极端,理论上一个垃圾回收结束和另一个垃圾收集结束可能在几纳秒内开始。例如,如果您的应用程序处于从满堆中死亡的最后阶段,或者如果它正在分配病理上较大的数组,则可能会发生这种情况。

所以:

我们是在谈论微秒,毫秒,分钟,天吗?

可能以上所有,尽管如果你在实践中观察它们,前两个肯定会令人不安。

行为良好的应用程序不应过于频繁地运行 GC。如果应用程序每秒多次触发年轻空间集合,则这可能会导致性能问题。过于频繁的“完整”收集更糟,因为它们的影响更大。但是,对于设计不佳/实现不佳的应用程序来说,这样做当然是合理的。


还有一个问题是,GC运行之间的间隔并不总是有意义的。例如,一些 HotSpot GC 实际上具有与普通应用程序线程同时运行的 GC 线程。如果您有足够的内核、足够的 RAM 和足够的内存总线带宽,则持续运行的并发 GC 可能不会明显影响应用程序性能。

术语说明:

  • 严格来说,并发 GC 是 GC 可以与应用程序线程同时运行的 GC。
  • 严格来说,并行GC是GC本身使用多个线程的GC。
  • GC 可以是并发的,而不是并行的,反之亦然。

答案 2

这是一个相对的术语。年轻的收藏可能是每秒多次,甚至几个小时。老一代的收藏可以每隔几秒钟,直到每天。在大多数系统中,您应该期望拥有比旧集合更多的年轻集合。

它不太可能是很多天。如果GC发生得太频繁,例如相距100毫秒<<,您将获得一个作为JVM发生前奏。OutOfMemoryError: GC Overhead Exceeded