Java的垃圾收集何时释放内存分配?

我用Java创建了一个对象,命名为FOO。 FOO包含大量数据..我不知道对于我已经拉入ram进行操作的十兆字节文本文件。(这只是一个例子)

这显然是一个巨大的空间,我想从内存中释放它。 我将FOO设置为NULL。

这会自动释放内存中的空间吗? 或者加载的文本文件占用的内存是否会自动垃圾收集?

将任何对象的引用设置为null ,它用于垃圾回收。 它仍然占用内存,直到垃圾收集器实际运行。 无法保证GC何时运行,除非它在OutOfMemoryException之前肯定会运行并从无法访问的对象中回收内存。

您可以调用System.gc()来请求垃圾收集,但是,这就是请求。 GC可自行决定运行。

在某些情况下,使用WeakReference可能会有所帮助。 请参阅Brian Goetz 撰写的这篇文章 。

实际上该对象未命名为FOO。 FOO是不是对象的变量的名称; 变量包含对象的引用 。 可能有几个不同的变量包含对同一对象的引用。

垃圾收集器通过自动检测无法访问的对象来工作:这些是应用程序不能再使用的对象,因为它无可挽回地忘记了它们的位置(应用程序可能访问它所引用的任何对象,包括存储在字段中的引用)它可以访问的对象,等等)。

当您设置FOO = null ,假设FOO在该点包含对象的最后一个可达参考,则在以下意义上立即释放内存:在FOO设置null的非常时钟周期,对象变为不可达。 因此,垃圾收集器会注意到无法访问的对象并回收相应的内存块; 也就是说,GC会在下次运行时遇到麻烦。 当然,构成对象的实际位可能在存储器中稍微延迟; 但是该块仍然是“免费的”,因为内存分配器将在空闲内存紧张时自动运行GC。 从应用程序的角度来看,该对象与死机一样好,并且相应的内存是空闲的,因为该内存将在下次应用程序需要时重用。 整件事是自动的。

关于操作系统,事情要复杂一些。 如果从应用程序的角度来看,无法访问的对象是空闲内存,那么就操作系统而言,它仍然是专用于正在运行的进程的RAM块。 只有当GC(在操作系统级别,是进程的一部分)实际运行时,才会将该RAM块返回给操作系统,注意到该对象无法访问,并且屈服于将块返回给操作系统。 当GC大量运行时,取决于GC技术以及应用程序如何分配对象; 此外,一些GC永远不会回退操作系统的块(GC知道它释放的块,内存分配器将随意重用它,而不是其他进程)。

System.gc()是VM的提示,因此它现在运行GC。 forms上,它只是一个提示,VM可以自由地忽略它。 实际上,它运行GC,除非指示VM不遵守这些命令(使用Sun的JVM,这是特定命令行标志的问题)。 即使GC运行,它也不一定会将内存返回给操作系统。 System.gc()并不是非常有用。

设置foo = null; 并不意味着foo会立即被垃圾收集。 相反,它会在GC下次运行时收集,如果可以的话。 当收集foo ,它拥有唯一参考的任何对象也将有资格收集并因此被收集。

请注意,即使调用System.gc()也不能保证JVM会立即执行此操作。

System.gc()只是一个请求,并不能保证它会立即生效。

无法保证JVM会立即执行此操作,您可以尝试使用System.gc()强制它

在“销毁”引用后,垃圾收集器将释放内存。 i.3将对象引用设置为null。 您可以使用强制垃圾收集选项,但应小心使用它。 垃圾收集器旨在使用优化的调度,因此调用System.gc()可能会破坏rhythem,并且可能由于不必要的任务切换而导致性能降低。

或者,您可以考虑一种允许您不将大量数据加载到内存中的方法。 如果你可以通过改进你的代码来获得更好的代码。