【问题标题】:How can I make an Object live in memory only for some part of a function in JAVA?如何使对象仅在 JAVA 中某个函数的某些部分存在于内存中?
【发布时间】:2017-10-22 08:00:57
【问题描述】:

我有一个运行很长时间的函数,我在该函数中声明并分配了一个对象。现在,据我所知,只要该函数正在运行,该对象将至少在内存中存在,之后如果没有其他对象引用它,它将可用于垃圾收集。现在,我希望这个对象在函数完成运行之前可用于垃圾收集。在编码器中:

     public void foo(){
             String title;
             Object goo=getObject();  //getObject is some other function 
     //which returns Object and can be null and I want Object to be in memory from here
             if(goo!=null)title=goo.getString("title"); 
           //after the last line of code I want Object to be available for garbage 
    // collection because below is a long running task which doesn't require Object.

              for(int i=0;i <1000000;i++)     //long running task
        {
        //some mischief inside with title 
        }

            }

现在从上述任务中,我希望 Object 在 for 循环开始之前可用于垃圾收集。我可以在 for 循环之前将两行代码放在花括号内吗?如果没有,我该怎么做才能完成这项任务?

【问题讨论】:

  • 对象重驻留在内存中吗?这是您想要这样做的原因吗?
  • 我已经问过这个问题了,原因是为什么要在内存中保留不必要的对象,不管它们是大是小。
  • 对于小对象和低内存占用且没有内存紧缩,您无需关心。此外,GC 是非确定性的。因此,即使将其分配给 null 也不能保证它会立即被收集。

标签: java garbage-collection


【解决方案1】:

即使您不执行任何操作,对象也不会在循环期间停留。一旦您的代码通过最后访问点,Java 就会发现该对象不可访问。

可达对象是可以在任何潜在的持续计算中从任何活动线程访问的任何对象。如今,JVM 在确定可达性方面非常聪明。如果它发现在循环期间或之后没有可能访问goo 的代码延续,Java 会在最后一次访问之后使对象符合垃圾收集的条件。即使最后一个访问检查器非常保守,没有对 goo 的访问权也足以让 JVM 相信该对象不再可访问。

更多详情请见this Q&A

【讨论】:

    【解决方案2】:

    完成对象后,将null 分配给goo 将使其无法再通过goo 访问。如果没有其他东西保持它可以访问,那么它将有资格进行垃圾收集。

    安排您的代码以使goo 变量超出范围可能具有相同的效果,但该方法取决于 JIT 编译器/GC 优化跟踪 out-of 的能力-范围变量。这取决于平台。

    【讨论】:

    • 将代码括在花括号中是否有同样的作用?
    • 答案将取决于实现。
    【解决方案3】:

    你可以尝试分配

    goo = null;
    

    在您从中获得所需信息后,如果没有其他对象引用它,gc 可能会收集该对象。

    有关其他一些想法,请参阅Marking an Object To Be Removed In The GC

    【讨论】:

    • 将代码括在花括号中是否有同样的作用?
    【解决方案4】:

    您可以将变量、函数调用和if 测试放在block 中。喜欢,

    { // <-- add this
        Object goo = getObject();
        if (goo != null) { // <-- just because you can omit braces, doesn't mean 
                           //     you should.
            title = goo.getString("title"); 
        }
    } // <-- and this, and then goo is out of scope.
    

    【讨论】:

    • if语句只有一行代码时,为什么不能省略大括号?
    • @kartik 省略大括号可以更容易地引入微妙(或不那么微妙)的错误,尤其是在嵌套的情况下 - 但通常足以建议反对这种做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2012-04-24
    • 2017-12-19
    • 2021-12-25
    • 2013-02-11
    • 2019-04-29
    • 1970-01-01
    相关资源
    最近更新 更多