Java中的垃圾收集器是否自动工作?

Java中的垃圾收集器是否自动工作?

问题描述:

我需要知道Java中的垃圾收集器是独立运行还是需要启动它。Java中的垃圾收集器是否自动工作?

+2

自动,自己 – 2010-06-18 06:20:24

+0

你可以毫不犹豫地告诉JVM垃圾收集,但它会根据自己的工作,当它需要的资源。 – gmhk 2010-06-18 06:37:00

+1

下一个问题:-)我的垃圾没有收集 - 为什么? – Blauohr 2010-06-18 07:57:49

它可以自行工作。你可以“建议”它运行,但这就是它。

+0

如果我没有记错的话,从使用Sun的HotSpot虚拟机的Java 1.4开始,'System.gc();'实际上是非操作的。其他VM:可能仍然对该呼叫作出反应。 – Esko 2010-06-18 07:44:40

是的,垃圾回收是由Java自动处理的。 当一个对象不再被任何变量引用时,Java会自动回收该对象使用的内存。这被称为垃圾收集。 仍然可以使用方法 System.gc()显式调用它。

+1

垃圾收集!=参考计数!可能有一个对象不再被引用,GC仍然没有释放它。尽管如此,还是有可能引用对象并进行垃圾收集。 (循环引用但无法访问的对象) – 2010-06-18 06:41:22

GC是一个deamon线程,它开始于您的JVM,并在JVM结束时结束(如果没有其他非deamon线程存在,JVM将停止运行)。

它在后台运行并在需要时启动。 JVM决定它何时运行,您可以“请求”它运行System.gc()

但我应该提到,你不能编写代码来依赖GC来运行(Java中的终结器不像C++中的析构函数)。人们往往对GC非常重视,然后忘记它是否是否定的,并导致内存泄漏并很难找到错误。

你可以指望的是,在你得到一个java.lang.OutOfMemoryError之前,GC鼓励并付出了努力。

+1

你应该澄清你的第三段 - 你是对的,你不应该依赖任何**特定的** GC时序等(包括使用终结器)。但是,您的警告可能意味着您不能指望GC运行*,即您应该以某种方式自己处理旧对象,这可能会造成混淆。 – 2010-06-18 07:12:03

+0

@Andrzej Doyle:JLS不保证终结者将被执行。 GC本身可能无法运行。这发生在使用少量对象的小程序上。 JVM会停止而不会调用GC。唯一确保终结器执行的是System.runFinalizersOnExit和Runtime.runFinalizersOnExit,现在已经废弃了一段时间。再一次,没有什么能保证GC能够运行。 – 2010-06-18 09:29:31

它根据优化算法自行工作以获得最佳性能。您可以执行强制垃圾回收,但不建议这样做,因为它可以阻止正常的垃圾回收模式,从而降低实际性能。

您应该在相关主题上阅读this Old SO Discussion

(这可能只是重复什么其他的答案是想说......不过,值得一说的这个清楚

Java垃圾收集器自动运行的需要,而且也没有必要开始它。

有一种静态方法(System.gc()),应用程序可以调用请求垃圾回收器运行“now”。但是:

  • 可以将JVM配置为不关注此请求。
  • 通常是坏主意发出此请求,因为它可以显着降低垃圾回收器的性能。一般来说,运行垃圾收集器的最佳时机是当有大量垃圾被收集时,并且只有JVM知道这可能是什么时候。

编辑 - 治愈大型垃圾收集延迟是改变JVM的垃圾收集器的属性来选择低延迟的收集器。在现代JVM中调用System.gc()并不是解决这个问题的方法。

+0

虽然我并不真的不同意你说的话,但在某些情况下,你想在有很多垃圾收集之前运行gc。大的gc运行会导致很长的延迟。在某些情况下,最好有几个小的比一个大。 – 2010-06-18 07:44:36

+1

@Mattias:那么你应该改变GC配置/实现,而不是依靠System.gc() – pgras 2010-06-18 08:50:16

我知道你必须调用System.gc()的唯一场合是当你创建大量的Direct ByteBuffers时。对于堆内存来说,OutOfMemoryError只会在完整的GC之后发生,但是对于直接内存,如果用尽(即使可能存在未被引用的缓冲区),则不会调用GC,因此您可能必须先自己调用它再试一次。

我希望这是在未来版本的Java中修复的东西。