【发布时间】:2014-05-24 04:06:36
【问题描述】:
当我们的应用程序完成其工作时,系统分配的内存(对于我们的 JVM)会发生什么情况。 GC 会删除所有对象吗? JVM如何释放内存,Mac OS如何清理JVM进程的内存。
当我使用 System.exit(1) 关闭我的应用程序时,我的 JVM 对 GC 和内存做了什么?
【问题讨论】:
标签: java garbage-collection operating-system
当我们的应用程序完成其工作时,系统分配的内存(对于我们的 JVM)会发生什么情况。 GC 会删除所有对象吗? JVM如何释放内存,Mac OS如何清理JVM进程的内存。
当我使用 System.exit(1) 关闭我的应用程序时,我的 JVM 对 GC 和内存做了什么?
【问题讨论】:
标签: java garbage-collection operating-system
垃圾收集器是否运行是特定于 JVM 的行为,但在大多数情况下不会(当我谈论操作系统时,我会解释原因)。如果您想在退出时执行一些操作(例如调用System.gc() 以建议垃圾收集器应该运行),那么您可以使用Runtime.addShutdownHook API。请注意,这是一个建议,可能并非在所有情况下都实际运行 GC。
在System.exit() 结束时,Java 将对 Mac OS 进行exit() 系统调用。发生这种情况时,Java 进程中的所有线程都将被操作系统暂停,并且它正在使用的内存页面将被操作系统释放。这与 Java 将在对象上运行的释放不同,后者释放了一块(通常非常小的)内存供 Java 进程重用,但 Java 仍然可以完全控制内存并且操作系统不能将其交给另一个过程。当操作系统释放一页内存时,这意味着现在有一个物理内存区域可以由另一个进程或操作系统本身分配(即文件系统缓存)。由于操作系统仅按一页内存的倍数(通常约为 4k 字节)分配和释放内存,因此它可以比 Java 更快地释放内存(它可能在单个页面内处理许多对象)。
Java 在退出之前(通过在退出时运行 GC)释放所有正在使用的内存没有意义的原因是,一旦程序退出,这些页面中的内容就无关紧要了,因为没人关心Java 进程中最后保存了哪些数据。操作系统将确保它分配给新进程的任何页面都预先清除旧数据。
【讨论】:
当您调用 System.exit(1) Garbage Collector 可能会或可能不会运行时,这里无法保证。 Mac OS(或任何其他操作系统)如何为特定进程回收内存完全取决于您使用的操作系统。这里的保证是一旦一个进程完成,内存就会被回收。
我假设最简单的模式是知道进程使用的内存的开始和结束地址,一旦完成它就会被回收。但我不确定。
您可以在这里阅读一些关于 Mac OS 内存管理的信息:Mac OS
【讨论】: