【问题标题】:How does Garbage Collector frees up memory before JVM exits?Garbage Collector 如何在 JVM 退出前释放内存?
【发布时间】:2021-10-12 10:59:36
【问题描述】:

我读过垃圾收集器在java中作为daemon线程运行,而守护线程具有低优先级,它们在后台运行,支持其他非守护线程,这就是JVM不等待守护线程的原因线程来完成它们的执行。

如果所有non-daemon 线程都已退出但仍有一定数量的内存占用,那么Garbage Collector 如何在JVM 停止之前释放资源而不导致任何内存泄漏?

【问题讨论】:

  • 如果进程停止,它不需要清理自己的内存,操作系统会在进程完成后将其释放。 Java 也一样:GC 不需要运行,操作系统只是终止 java 进程并释放任何仍然占用的内存。
  • @luk2302 这正是我的猜测,但在维基百科上它说“内存泄漏是一种资源泄漏,当计算机程序错误地管理内存分配 [1]不再需要不发布”
  • 这是真的,但与问题无关。操作系统不关心您的应用程序潜在的内存泄漏。您的应用程序可能会冻结,因为它弄乱了自己的内存,如果操作系统检测到这一点,或者用户检测到它并退出应用程序,操作系统将终止应用程序并回收内存,故事结束。当然,操作系统本身可能存在内存泄漏,此时操作系统可能会在某个时候通过基本上重新启动计算机来“终止”。您有不同级别的应用程序,内存泄漏/管理分别发生在所有这些级别上。
  • 操作系统分配给 JVM 的内存块与 JVM 本身如何管理该内存中的对象(这是 GC 操作的对象)(包括终结器)之间存在差异。当 JVM 停止时,所有内容都会释放回操作系统。
  • @ThorbjørnRavnAndersen 让它更清晰!谢谢!

标签: java garbage-collection jvm


【解决方案1】:

GC 不会在 JVM 退出之前释放内存。

实际发生的是,当JVM退出时,JVM运行所在的进程也退出了1。当进程退出时,操作系统会回收进程正在使用的所有 RAM 和交换页面(独占)并回收其虚拟内存页表。

如果您的 Java 程序(或 C/C++ 程序)存在内存泄漏,那么一旦清理了进程,这无关紧要。操作系统始终知道哪些 RAM / 交换页面属于哪个进程。什么都没有丢失。


1 - 如果 JVM 是由 C / C++ 应用程序使用(例如)JNI 启动的,那么该进程不一定会在此时退出。然后由 C/C++ 应用程序来决定要做什么。但是在这种情况下 GC 也不会清理。

【讨论】:

  • 即使不退出进程,将整个堆内存作为单个块释放也不会有问题,就像分配它一样。
  • JNI_DestroyJavaVM() 会这样做吗?
  • 我不会赌它作为参考实现。 Hotspot JVM 不支持多个 JVM 用于一个进程,甚至一个接一个也不支持。这导致了诸如the documentation of JNI_DestroyJavaVM 以“Unloads a Java VM...”开头和“Unloading of the VM is not supported”之类的搞笑事情。那么,我们能在多大程度上指望“……并回收其资源”?我不知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 2021-09-19
  • 1970-01-01
  • 2021-07-01
相关资源
最近更新 更多