JVM / GC是否在程序/线程退出时调用`finalize()`? [英] Does JVM/GC call `finalize()` on program/thread exit?

查看:112
本文介绍了JVM / GC是否在程序/线程退出时调用`finalize()`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PS:我确实知道如何正确清理,而不依赖于 finalize()

PS: I do know how to cleanup correctly, without depending on finalize().

Java不保证在程序退出时,会进行适当的垃圾收集吗?

Does Java not guarantee that on program exit, proper garbage collection will be done?

例如假设我已经在缓存中保留了一些数据而不是频繁地序列化,我还实现了 finalize(),希望如果由于任何原因(崩溃除外)我的程序优雅地退出,然后我的代码在finalize()方法中将缓存写入DB / file / some-storage。但是根据下面的小实验,似乎JVM没有优雅地清理内存,它只是退出。

E.g. lets say I've kept some data in cache instead of serializing it frequently, I also implemented finalize() with the hope that if due to whatever reason (except crash) my program exits gracefully, then the cache would be written to DB/file/some-storage by my code in finalize() method. But according to following little experiment it seems like JVM doesn't cleanup memory "gracefully", it just exits.

Java规范(参见程序退出)说明了退出时如何处理内存/ gc。或者我应该查看规范的其他部分吗?

Java spec (see program exit) says NOTHING abt how memory / gc is handled on exit. Or should I have been looking at a different section of the spec?

在Windows 7上使用1.6.0.27 64位获取以下示例(最后输出)

Take the following example (output at the end) using 1.6.0.27 64 bits, on Windows 7

public class Main {

        // just so GC might feel there is something to free..
    private int[] intarr = new int[10000];

    public static void main(String[] args) {
        System.out.println("entry");
        Main m = new Main();
        m.foo();
        m = new Main();
        // System.gc();
        m.foo();
        m = null;
        // System.gc();
        System.out.println("before System.exit(0);");
        System.exit(0);
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize()");
        super.finalize();
    }

    public void foo() { System.out.println("foo()"); }
}

/*
 * Prints:
 * entry 
 * foo() 
 * foo() 
 * before System.exit(0);
 */

变化:


  • 如果我取消注释任何一个 System.gc()那么没有 finalize()被叫。

  • 如果我取消注释 System.gc()然后 finalize()被调用两次。

  • 是否调用 System.exit()对<$ c $是否有效c> finalize()是否被调用。

  • If I uncomment any one System.gc() then no finalize() is called.
  • If I uncomment both System.gc() then finalize() is called twice.
  • Whether System.exit() is called or not has no effect on whether finalize() is called or not.

推荐答案

不,Java不保证在程序退出时GC会触发。如果要在退出时执行操作,请使用 Runtime.addShutdownHook 方法。阅读这篇关于SPEC所说内容的文章。

No, Java does not guarantee that on program exit the GC will trigger. If you want an operation to peform on exit use Runtime.addShutdownHook method. Read this Sun article on what the SPEC says.


Java平台的规范很少有关于
的承诺,垃圾收集实际上是如何工作的。以下是Java Virtual
机器规范(JVMS)对内存管理的看法。

The specification for the Java platform makes very few promises about how garbage collection actually works. Here is what the Java Virtual Machine Specification (JVMS) has to say about memory management.

堆是在虚拟机启动时创建的。
对象的堆存储由自动存储管理系统回收(已知
作为垃圾收集器);对象永远不会被显式释放。
Java虚拟机假定没有特定类型的自动存储
管理系统,并且可以根据实现者的系统要求选择
存储管理技术.1虽然看起来好像是
令人困惑的是,垃圾收集模型并非严格定义
实际上是重要且有用的 - 严格定义的垃圾
集合模型可能无法在所有平台上实现。
同样,它可能排除有用的优化并且长期损害平台的
性能。

The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements.1 While it can seem confusing, the fact that the garbage collection model is not rigidly defined is actually important and useful-a rigidly defined garbage collection model might be impossible to implement on all platforms. Similarly, it might preclude useful optimizations and hurt the performance of the platform in the long term.

虽然没有一个地方包含
的完整定义需要垃圾收集器行为,GC模型的大部分是通过Java语言
规范和JVMS中的许多部分隐式指定的
。虽然无法保证所遵循的确切
流程,但所有兼容的虚拟机都共享本章所述的基本
对象生命周期。

Although there is no one place that contains a full definition of required garbage collector behavior, much of the GC model is implicitly specified through a number of sections in the Java Language Specification and JVMS. While there are no guarantees about the exact process followed, all compliant virtual machines share the basic object lifecycle described in this chapter.

这篇关于JVM / GC是否在程序/线程退出时调用`finalize()`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆