垃圾收集什么时候在java中工作?

我知道有很多关于java垃圾收集的文章但是在搜索之后我并不确切地知道“什么时候垃圾收集在java应用程序中运行?(当应用程序重启或者它仍在运行时)”

Garbage Collector是一个dameon线程。 一个dameon线程在应用程序后面运行。 它由JVM启动。 当所有非dameon线程停止时,线程停止。

JVM控制垃圾收集器; 它决定何时运行垃圾收集器。 当JVM意识到内存不足时,它会运行垃圾收集器。 可以通过将参数传递给JVM来调整GC的行为。

可以从java程序中请求垃圾收集,但不能保证jvm.Check将处理此请求如何在Java中强制垃圾收集?

学到更多 ..

垃圾收集定期与程序一起运行。 它是JVM的一部分。

什么时候它确实运行? 嗯,这是不可预测的,依赖于版本的,应该被视为可以随时运行。

当变量超出范围时,应用程序会告诉JVM它完成了那段内存。 然后,当垃圾收集器运行时,它将释放这些资源供操作系统使用。

例如

 String capitalizeAll(String s) { char[] chars = s.toCharArray(); for(int i = 0; i < chars.length; i++) chars[i] -= 32; return new String(chars); } 

方法返回后,方法中分配的char[] chars将超出范围。 该程序告诉JVM它已完成这些资源,下次GC运行时它们将被释放。

有趣的是,JVM考虑了应用程序告诉它已准备好收集的程度。 这意味着如果您的应用程序执行了大量不必要的复制或装箱操作,JVM将经常运行并导致您的应用受到性能影响。

这主要是针对特定于实现的。

最原始类型的垃圾收集器,串行GC将在分配期间找不到足够的可用空间时触发(使用世代GC通常意味着年轻代已满)。 然后它通过触发mutator线程上的安全点来挂起整个JVM,并在单个线程上工作,这称为“停止世界暂停”。在这种情况下,您可以说GC可以由任何分配引起。

除此之外,一些GC还可以同时为mutators进行后台工作,例如Hotspot的CMS 。 但它仍然需要停止世界暂停一些工作,它们往往比串行GC更短。 对于CMS,它仍然由分配触发,但也在后台线程上完成一些工作。

Azul Zing的并发压缩收集器也可以 – 正如其名称所说的那样 – 或多或少地一直在专用线程上进行收集。 它仍然需要来自mutator线程的合作,但是没有STW暂停。 所以这个案例可以说GC一直在后台运行,并在前台做了一点工作。

还有其他collections家,所以这不是一个全面的概述。 但总的来说,它是一个实现细节,可能会发生变化而不是人们应该依赖的东西。 一些GC甚至默认忽略System.gc(),因为它会破坏他们的启发式。

这是来自Kathy Sierra和Bert Bates的书SCJP Study Guide:

“垃圾收集器在JVM的控制之下.JVM决定何时运行垃圾收集器。在Java程序中,你可以要求JVM运行垃圾收集器,但在任何情况下都无法保证JVM将遵守。在它自己的设备上,JVM通常会在检测到内存不足时运行垃圾收集器。经验表明,当您的Java程序发出垃圾收集请求时,JVM通常会批准您的请求订单很短,但没有任何保证。只要您认为可以依赖它,JVM就会决定忽略您的请求。“