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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12599044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:30:12  来源:igfitidea点击:

What the frequency of the Garbage Collection in Java?

javagarbage-collection

提问by auser

Page 6 of the the document Memory Management in the Java HotSpot? Virtual Machinecontains the following paragraphs:

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

Young generation collections occur relatively frequently and are efficient and fast because the young generation space is usually small and likely to contain a lot of objects that are no longer referenced.

Objects that survive some number of young generation collections are eventually promoted, or tenured, to the old generation. See Figure 1. This generation is typically larger than the young generation and its occupancy grows more slowly. As a result, old generation collections are infrequent, but take significantly longer to complete

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

在一定数量的年轻代集合中幸存下来的对象最终会被提升或终身使用到老年代。参见图 1。这一代通常比年轻代大,并且其占用率增长得更慢。因此,老年代收集很少,但需要更长的时间才能完成

Could someone please define what "frequent" and "infrequent" mean in the statements above? Are we talking microseconds, milliseconds, minutes, days?

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

回答by Stephen C

It is not possible to give a definite answer to this. It really depends on a lot of factors, including the platform (JVM version, settings, etc), the application, and the workload.

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

At one extreme, it is possible for an application to never trigger a garbage collector. It might simply sit there doing nothing, or it might perform an extremely long computation in which no objects are created after the JVM initialization and application startup.

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

At the other extreme it is theoretically possible for one garbage collection end and another one to start within few nanoseconds. For example, this could happen if your application is in the last stages of dying from a full heap, or if it is allocating pathologically large arrays.

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

So:

所以:

Are we talking microseconds, milliseconds, minutes, days?

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

Possibly all of the above, though the first two would definitely be troubling if you observed them in practice.

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

A well behavedapplication should not run the GC too often. If your application is triggering a young space collection more than once or twice a second, then this could lead to performance problems. And too frequent "full" collections is worse because their impact is greater. However, it is certainly plausible for a poorly designed / implemented application to behave like this.

一个表现良好的应用程序不应该太频繁地运行 GC。如果您的应用程序每秒触发一次或两次以上的年轻空间收集,那么这可能会导致性能问题。过于频繁的“完整”集合更糟糕,因为它们的影响更大。但是,设计/实施不佳的应用程序具有这种行为当然是合理的。



There is also the issue that the interval between GC runs is not always meaningful. For instance some of the HotSpot GCs actually have GC threads running concurrently with normal application threads. If you have enough cores, enough RAM and enough memory bus bandwidth, then a constantly running concurrent GC maynot appreciably affect application performance.

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

Terminology note:

术语说明:

  • Strictly speaking a concurrent GC is one where the GC can run at the same time as the application threads.
  • Strictly speaking a parallel GC is one where the GC itself uses multiple threads.
  • A GC can be concurrent without being parallel, and vice versa.
  • 严格来说,并发 GC 是 GC 可以与应用程序线程同时运行的一种。
  • 严格来说,并行 GC 是 GC 本身使用多个线程的一种。
  • GC 可以并发而不是并行,反之亦然。

回答by Peter Lawrey

Its a relative term. Young collections could be many times a seconds up to a few hours. Old generations collections can be every few seconds, up to daily. You should expect to have many more young collections than old collections in a most systems.

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

Its highly unlikely to be many days. If the GC occurs too often e.g. << 100 ms apart you get get a OutOfMemoryError: GC Overhead Exceededas the JVM prevenets that from happening.

它极不可能是很多天。如果GC 发生得太频繁,例如<< 100 毫秒,你会得到一个,OutOfMemoryError: GC Overhead Exceeded因为JVM 阻止了这种情况的发生。

回答by Ravi Bhatt

As it is, the terms "frequent" , "infrequent" are relative. And the timings are, in fact, not fixed. It depends on the system in question. It depends on lots of things like:

事实上,术语“频繁”、“不频繁”是相对的。事实上,时间并不是固定的。这取决于相关系统。这取决于很多事情,例如:

  • Your heap size and settings for different parts of the heap (young, old gen, perm gen)
  • Your application's memory behaviour. How many objects does it create and how fast? how long those objects are referenced etc?
  • 您的堆大小和堆不同部分的设置(年轻、老一代、烫发)
  • 您的应用程序的内存行为。它创建了多少个对象,速度有多快?这些对象被引用了多久等等?

If your application is monster memory eater, gc would run as if its running for its life. If your application does not demand too much of memory, then gc would run at intervals decided by how full the memory is.

如果您的应用程序是巨大的内存吞噬者,则 gc 会像它的生命周期一样运行。如果您的应用程序不需要太多内存,那么 gc 将按照内存满情况决定的时间间隔运行。

回答by user3817323

TL DL: "Frequent" and "infrequent" are relative terms that depends on the memory allocation rate and the heap size. If you want a precise answer, you need to measure it yourself for your particular application.

TL DL:“频繁”和“不频繁”是依赖于内存分配率和堆大小的相对术语。如果您想要一个准确的答案,您需要针对您的特定应用自行测量。

Let's say your app has two modes, mode-1 allocates memory and does computation and mode-2 sits idle.

假设您的应用程序有两种模式,模式 1 分配内存并进行计算,模式 2 处于空闲状态。

If mode-1 allocation is smaller than the heap available, no gc need to occur until it finishes. Maybe it used so little RAM that it could do a second round of mode-1 without collection. However, eventually you'll run out of free heap, and jvm will perform an "infrequent" collection.

如果模式 1 分配小于可用堆,则在完成之前不需要进行 gc。也许它使用的 RAM 太少,以至于它可以在不收集的情况下进行第二轮模式 1。但是,最终您将耗尽可用堆,并且 jvm 将执行“不频繁”的收集。

However, if mode-1 allocation is a significant fraction of, or larger, than the young-generation heap, collection would happen more "frequently". During the young gen collection, allocations that survive (imagine data is needed through the entire mode-1 operation), will be promoted to old-gen, giving the young-gen more room. Young-gen allocation and collection can now continue. Eventually old-gen heap would run out, and must be collected, thus "infrequently".

但是,如果模式 1 分配占年轻代堆的很大一部分或更大,则收集将更“频繁地”发生。在年轻代收集期间,幸存下来的分配(想象数据在整个模式 1 操作中需要),将被提升到老代,给年轻代更多的空间。Young-gen 分配和收集现在可以继续。最终 old-gen 堆会用完,并且必须被收集,因此“很少”。

So then, how frequent is frequent? It depends on the allocation rate and the heap size. If jvm is bumping into the heap limit often, it'll collect often. If there is plenty of heap (let's say 100GB), then jvm doesn't need to collect for a long long time. The down side is that when it finally does a collection, it might take a long time to free 100GB, stopping the jvm for many seconds (or minutes!). The current JVMs are smarter than that and would occasionanlly force a collection (preferably in mode-2). And with parallel collectors, it could happen all the time if necessary.

那么,频繁的频率是多少?这取决于分配率和堆大小。如果 jvm 经常遇到堆限制,它会经常收集。如果有足够的heap(比如说100GB),那么jvm就不需要长时间收集了。不利的一面是,当它最终进行收集时,可能需要很长时间才能释放 100GB,从而使 jvm 停止数秒(或数分钟!)。当前的 JVM 比这更智能,偶尔会强制收集(最好在模式 2 中)。对于并行收集器,如有必要,它可以一直发生。

Ultimately, the frequency is task and heap dependent, as well as how various vm parameters are set. If you want a precise answer, you must measure them yourself for your particular application.

最终,频率取决于任务和堆,以及各种 vm 参数的设置方式。如果您想要一个准确的答案,您必须针对您的特定应用自行测量它们。

回答by CAMOBAP

Because spec says "relatively frequently" and infrequent (regarding Young generation), we can't estimate the frequency in absolute units like microseconds, milliseconds, minutes or days

因为规范说“相对频繁”和不频繁(关于年轻代),我们不能用绝对单位来估计频率,比如微秒、毫秒、分钟或天