Java的垃圾收集什么时候可以释放内存?

Mag*_*ero 14 java garbage-collection

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

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

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

sam*_*aur 15

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

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

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


Tho*_*nin 8

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

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

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

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

System.gc()是对VM的提示,以便它现在运行GC.形式上,它只是一个提示,VM可以自由忽略它.在实践中,运行GC,除非VM奉命不服从这样的命令(Sun的JVM,这是一个特定的命令行标志的问题).即使GC运行,它也不一定会将内存返回给操作系统.System.gc()不是非常有用.


Tim*_*der 5

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


mhs*_*ams 5

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

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