使用线程安全的针对本地和全局变量的Java垃圾收集

时间:2015-03-06 05:55:33

标签: java garbage-collection thread-safety global-variables local-variables

下面的代码片段中,以TIME为单位的垃圾收集效率更高

Class Test{...}

本地变量

private void function(){
   Test test = new Test();
    ....
}

全局变量

Test test = null; 
private void function(){   
   if(test == null){
     test = new Test();   
   } 
}
  

假设经常调用function()

修改

你们都很好。回答得很好。 现在我来点

  

CASE-1比CASE-2更有效GC,但另一方面CASE-1   不是线程安全的。所以两者都有利弊

3 个答案:

答案 0 :(得分:1)

如果构造函数有副作用,那么你的两个选项可以做两件事。


如果Test带有状态,则选项1和选项2可能不再等效(并且选项2可能不是线程安全的)。

例证:许多人犯了使用Java的日期或数字格式对象(如选项2)的错误。这种方法效果不佳,因为它们不是线程安全的。


假设Test完全没有状态并且调用构造函数没有副作用(这两者似乎都暗示了),那么选项3如何:

private static final Test test = new Test();

private void function(){
    .....
}

根本没有GC活动。


或者,如果Test确实带有状态或者某种程度上不是线程安全的,并且您想要在紧密循环中调用function,则选项4:

private void function(Test test){
}

void theCaller(){
    Test test = new Test();
    for (int i=0; i<10000; i++) {
       function(test);
    }
}

由于该方法为private,因此您可以自由地转移到以性能名称调用它的不太方便的方式。

答案 1 :(得分:1)

在案例1中,创建了一个测试,并且在每次调用时都符合GC的条件,这会产生大量垃圾。在案例2中,它创建了一次,可能从未进行过GCed。

为什么我们不总是使用选项2 - 它可能不是线程安全的。让我们用SimpleDateFormat替换Test,而function()将需要同步,否则它将无法在多线程应用程序中运行。同步也很昂贵。因此,我们需要确定哪个选项更适合每次新对象或同步。

答案 2 :(得分:0)

这取决于函数的使用以及在问题集中定义对象的内容。我总是说,只在需要时创建对象。没有理由让一个物体不被使用。如果您计划在函数之外使用该对象,则首先需要将其初始化为全局,然后在需要时创建该对象。

您不应该担心Java的垃圾收集效率。这很有效率。只要你不是动态地不断地在100秒和更多的物体上制造100个,我就不用担心了。