Java 使用线程安全对局部和全局变量进行垃圾收集
Java Garbage collection against Local and Global variable with Thread Safe
以下哪个代码片段在 TIME 方面的垃圾收集效率更高
Class Test{...}
局部变量
private void function(){
Test test = new Test();
....
}
全局变量
Test test = null;
private void function(){
if(test == null){
test = new Test();
}
}
Let assume function() call frequently
编辑
你们都很好。回答得很好。
现在我要说
CASE-1 is more GC efficient than CASE-2 but on the other hand CASE-1
is not thread safe. So both having pros and cons
.
好吧,这取决于函数的使用以及对象在问题集中被定义为做什么。我总是说,只在需要时创建对象。没有理由让一个对象闲置不被使用。如果您计划在您的函数之外使用该对象,您将希望首先将其全局初始化为 null,然后在需要时创建该对象。
您不必担心 Java 的垃圾收集效率。这是有效的。只要你不是不断动态地制作 100 上 100 和更多对象,我就不会担心。
如果构造函数有副作用,您的两个选项会做两件不同的事情。
如果 Test
携带状态,选项 1 和选项 2 可能不再等效(并且选项 2 可能不是线程安全的)。
恰当的例子:许多人错误地使用了 Java 的日期或数字格式对象,例如选项 2。这效果不佳,因为它们不是线程安全的。
假设 Test
是完全无状态的并且调用构造函数没有副作用(你似乎暗示了这两者),选项 3 怎么样:
private static final Test test = new Test();
private void function(){
.....
}
根本没有 GC activity。
或者,如果 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 中,创建了一个测试,并且在每次调用时都符合 GC 的条件,这会产生大量垃圾。在情况 2 中,它被创建一次并且可能永远不会被 GC。
为什么我们不总是使用选项 2 - 它可能不是线程安全的。让我们用 SimpleDateFormat 和 function() 替换 Test 将需要同步,否则它将无法在多线程应用程序中工作。同步也很昂贵。所以我们需要决定哪个选项是每次新对象或同步更好。
以下哪个代码片段在 TIME 方面的垃圾收集效率更高
Class Test{...}
局部变量
private void function(){
Test test = new Test();
....
}
全局变量
Test test = null;
private void function(){
if(test == null){
test = new Test();
}
}
Let assume function() call frequently
编辑
你们都很好。回答得很好。 现在我要说
CASE-1 is more GC efficient than CASE-2 but on the other hand CASE-1 is not thread safe. So both having pros and cons
.
好吧,这取决于函数的使用以及对象在问题集中被定义为做什么。我总是说,只在需要时创建对象。没有理由让一个对象闲置不被使用。如果您计划在您的函数之外使用该对象,您将希望首先将其全局初始化为 null,然后在需要时创建该对象。
您不必担心 Java 的垃圾收集效率。这是有效的。只要你不是不断动态地制作 100 上 100 和更多对象,我就不会担心。
如果构造函数有副作用,您的两个选项会做两件不同的事情。
如果 Test
携带状态,选项 1 和选项 2 可能不再等效(并且选项 2 可能不是线程安全的)。
恰当的例子:许多人错误地使用了 Java 的日期或数字格式对象,例如选项 2。这效果不佳,因为它们不是线程安全的。
假设 Test
是完全无状态的并且调用构造函数没有副作用(你似乎暗示了这两者),选项 3 怎么样:
private static final Test test = new Test();
private void function(){
.....
}
根本没有 GC activity。
或者,如果 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 中,创建了一个测试,并且在每次调用时都符合 GC 的条件,这会产生大量垃圾。在情况 2 中,它被创建一次并且可能永远不会被 GC。
为什么我们不总是使用选项 2 - 它可能不是线程安全的。让我们用 SimpleDateFormat 和 function() 替换 Test 将需要同步,否则它将无法在多线程应用程序中工作。同步也很昂贵。所以我们需要决定哪个选项是每次新对象或同步更好。