【问题标题】:garbage collector doubts垃圾收集器的疑惑
【发布时间】:2012-06-28 06:20:15
【问题描述】:

我有一些关于 java 垃圾收集器的问题。 首先让我澄清一下我对Java GC.的理解 GC 是一个后台线程,当 JVM 启动时,将始终在后台运行。 每个对象都有一个 finalize() 方法。此方法用于释放 对象被销毁之前的系统资源。根据java专家的说法, 我们不应该将资源放在 finalize() 方法下以释放 系统资源。因为我们无法确定 GC 何时运行。但我们可以 通过调用System.GC() 请求GC 运行。

所以现在我的问题是,GC 是一个后台线程,将始终在后台运行。 现在我们怎么能说我们不知道GC 什么时候会运行呢?是不是这样的声明"we dont know when the GC will call finalize() method " 就是那个意思吗?如果这就是他们的意思,那么工作是什么 GC 的? GC 负责找出未使用的变量并从内存中删除。 那为什么GC也不能调用finalize()方法呢?

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

    现在我们怎么能说我们不知道 GC 什么时候会运行呢?

    GC 的功能由复杂的算法处理,这取决于底层操作系统和硬件。我们不能说,因为如果一个人告诉一个特定的 JVM 版本,它对其他 JVM 是无效的。所以最好我们不能依赖它。

    GC 的工作是什么。

    GC 找到引用较少的对象(读取类型的 ref. for more)并回收它们使用的内存。

    那么,为什么GC也不能调用finalize()方法?

    所以肯定会调用 finalize 方法,但不确定何时。因为即使您在 JVM 中知道 finalize() 方法何时运行,您也永远不知道在其他 JVM 中何时运行。因此,如果您在 finalize 方法中处理一些非常昂贵的资源,您的程序可能会在其他 JVM 中崩溃。

    【讨论】:

    • 我们能否确保不再需要一个对象,将其从内存中释放?那为什么不能调用finalize()方法释放系统资源呢?
    • 你无法确定。您只能通过使其无引用来使其仅符合 GC 的条件。 finalize() 方法将被调用,但你不确定何时
    • -1 因为 JVM 规范确实为自动存储管理设置了条件,即。垃圾收集器。编写 JLS 和 JVM 规范是为了确保 Java 的跨平台特性,只是因为平台的模糊性永远不会成为问题。
    • 好吧..你是说每个 JVM 的行为都相似,无论底层平台是什么。我说的不是模棱两可,而是他们跨平台行为的一致性。即使对于单个平台,我们也有不同的不同 JVM 实现
    【解决方案2】:

    简单来说,GC 会在不确定的时间运行,因此如果依赖finalize 来释放系统资源,系统资源将无法及时释放。当大多数程序逻辑应该很容易设计为在不再使用时简单地释放资源时,等待 GC 获取持有系统资源的对象的堆空间是没有意义的。

    在一个有点相关的注释上。导致早期版本的 JVM 如此缓慢的问题之一是调用 finalize。因此,现代 JVM 将尽可能跳过调用 finalize。因此,依赖finalize 也会对性能产生影响。

    【讨论】:

    • 我们能否确保不再需要一个对象,将其从内存中释放?那为什么不能调用finalize()方法释放系统资源呢?
    • 可以的。依赖 finalize 被调用是有效的,但不是通常所做的。您可以阅读规范,第 12.6 章 - docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.6
    猜你喜欢
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 2011-11-07
    • 2013-04-01
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多