当前位置: 首页 > 面试题库 >

在最近的JVM中,无形引用仍然是一个问题吗?

孙思源
2023-03-14
问题内容

我正在阅读
Java平台性能
(很遗憾,自从我最初提出这个问题以来,链接似乎已经从互联网上消失了),而A.3.3节使我感到担忧。

我一直在假设一个超出范围的变量将不再被视为GC的根,但是本文似乎与此矛盾。

最近的JVM(尤其是Sun的1.6.0_07版本)是否仍然有此限制?如果是这样,那么我有很多代码需要分析

我问这个问题是因为该论文来自1999年-有时情况会发生变化,尤其是在GC领域。

由于该论文不再可用,我想换个说法。该文件暗示,在方法退出之前(而不是在代码块结束之前),在方法内部定义的变量将被视为GC根。因此,必须将变量设置为null,以允许对引用的对象进行垃圾收集。

这意味着在main()方法(或包含无限循环的类似方法)的条件块中定义的局部变量将导致一次性内存泄漏,除非您在变量超出范围之前将其清空。

所选答案中的代码很好地说明了这个问题。在文档中引用的JVM版本上,当foo对象在try块末尾超出范围时,不能对其进行垃圾回收。取而代之的是,JVM会一直保持打开引用直到main()方法的结尾,即使任何人都不可能使用该引用。

这似乎是这样的想法的起源,即即使变量将要超出范围,将变量引用为空也将有助于垃圾回收器。


问题答案:

此代码应清除它:

public class TestInvisibleObject{
  public static class PrintWhenFinalized{
    private String s;
    public PrintWhenFinalized(String s){
      System.out.println("Constructing from "+s);
      this.s = s;
    }
    protected void finalize() throws Throwable {
      System.out.println("Finalizing from "+s);
    }   
  }
  public static void main(String[] args) {
    try {
        PrintWhenFinalized foo = new PrintWhenFinalized("main");
    } catch (Exception e) {
        // whatever
    }
    while (true) {
      // Provoke garbage-collection by allocating lots of memory
      byte[] o = new byte[1024];
    } 
  }
}

在我的机器(jdk1.6.0_05)上打印:

从主体构造

从主要完成

因此看来问题已得到解决。

请注意,使用System.gc()代替循环不会由于某种原因而导致对象被收集。



 类似资料:
  • 我仍然被那些为了支持移动和转发而发明的规则弄糊涂了。有一件事我还不太确定: 转发引用是否只是rvalue引用(应用了引用折叠规则)? 如果它是一个rvalue引用,那么为什么函数: 不仅接受rvalues,还接受lvalues?

  • 我开发了一个应用程序,其中有导航抽屉和抽屉内的许多片段,所以我在打开片段内的片段时遇到问题,在一个片段中,当用户单击列表视图项时,我有列表视图,他们获得了与列表项相关的数据,所以我面临的问题是,它仍然单击不可见的列表,但单击 片段布局 开放片段代码

  • 问题内容: 我正在使用Backbone.js和Tornado Web服务器。在Backbone中接收收集数据的标准行为是作为JSON数组发送。 另一方面,由于以下漏洞,Tornado的标准行为是不允许JSON Array: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json- vulnerability.aspx 对于我来说

  • 问题内容: 是否有更新的JVM书籍可以反映最近的更新? 该链接中的任何书籍都读起来好吗?还是我应该避免其中的任何一部,因为它们已经过时了? 您知道此后出版过的书籍吗? 问题答案: 我读过的最好的Java书籍之一。 http://www.pearsonhighered.com/educator/product/Java- Performance/9780137142521.page 它被称为“ Ja

  • leetcode上的问题是:给定一个整数x,如果x是回文整数,则返回true。 当一个整数向后读取和向前读取相同的内容时,它就是一个回文。例如,121是回文,而123不是。 这是我的代码。 我很确定我的逻辑是正确的,但我在NetBeans上测试时没有发现错误,得到的结果是121是正确的,但10是正确的,因为它不是回文,所以应该是错误的?我很困惑,希望能得到一些帮助,更好地理解逻辑。

  • 我在CSV数据集配置中添加了CSV文件, 请点击网址查看图片 CSV 文件内容 将上述值传递给后请求,如下所示 点击链接查看图片 简单传递的请求数据具有参数名,而不是值,请参阅下面的示例请求