下面的代码片段中,以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 不是线程安全的。所以两者都有利弊
答案 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个,我就不用担心了。