在Java中赋值对象为null会影响垃圾收集吗?

时间:2021-05-07 03:49:36

Does assigning an unused object reference to null in Java improve the garbage collection process in any measurable way?

在Java中将未使用的对象引用赋给null是否以任何可度量的方式改进了垃圾收集过程?

My experience with Java (and C#) has taught me that is often counter intuitive to try and outsmart the virtual machine or JIT compiler, but I've seen co-workers use this method and I am curious if this is a good practice to pick up or one of those voodoo programming superstitions?

我的经验与Java(c#)告诉我,通常是反直觉,试图战胜虚拟机或JIT编译器,但是我看到同事使用这个方法,我很好奇如果这是一个很好的实践取或其中一个巫毒编程迷信呢?

13 个解决方案

#1


55  

Typically, no.

通常,没有。

But like all things: it depends. The GC in Java these days is VERY good and everything should be cleaned up very shortly after it is no longer reachable. This is just after leaving a method for local variables, and when a class instance is no longer referenced for fields.

但就像所有事情一样:这要看情况。现在Java中的GC非常好,在不能再访问之后,应该很快清理所有东西。这是在为局部变量留下一个方法之后,当类实例不再被字段引用时。

You only need to explicitly null if you know it would remain referenced otherwise. For example an array which is kept around. You may want to null the individual elements of the array when they are no longer needed.

如果您知道它将继续被引用,您只需要显式为空。例如,一个保存在周围的数组。当不再需要数组的各个元素时,您可能希望它们为空。

For example, this code from ArrayList:

例如,来自ArrayList的代码:

public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
             numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

Also, explicitly nulling an object will not cause an object to be collected any sooner than if it just went out of scope naturally as long as no references remain.

此外,显式地取消对象并不会导致对象被收集的时间比只要没有引用就自然地超出范围更短。

Both:

两个:

void foo() {
   Object o = new Object();
   /// do stuff with o
}

and:

和:

void foo() {
   Object o = new Object();
   /// do stuff with o
   o = null;
}

Are functionally equivalent.

在功能上是等价的。

#2


9  

In my experience, more often than not, people null out references out of paranoia not out of necessity. Here is a quick guideline:

在我的经验中,通常情况下,人们出于偏执而不是出于需要而放弃了引用。这里有一个简单的指导方针:

  1. If object A references object B and you no longer need this reference and object A is not eligible for garbage collection then you should explicitly null out the field. There is no need to null out a field if the enclosing object is getting garbage collected anyway. Nulling out fields in a dispose() method is almost always useless.

    如果对象A引用对象B,而您不再需要该引用,并且对象A不适合进行垃圾收集,那么您应该显式地将字段空出。如果封装对象正在收集垃圾,则不需要空出字段。在dispose()方法中取消字段几乎总是无用的。

  2. There is no need to null out object references created in a method. They will get cleared automatically once the method terminates. The exception to this rule is if you're running in a very long method or some massive loop and you need to ensure that some references get cleared before the end of the method. Again, these cases are extremely rare.

    不需要空出方法中创建的对象引用。一旦方法终止,它们将被自动清除。这个规则的例外是,如果您运行的是一个非常长的方法或一个大的循环,您需要确保在方法结束之前有一些引用被清除。同样,这种情况非常罕见。

I would say that the vast majority of the time you will not need to null out references. Trying to outsmart the garbage collector is useless. You will just end up with inefficient, unreadable code.

我想说,在绝大多数情况下,您不需要空出引用。试图智取垃圾收集器是没有用的。您最终会得到低效的、不可读的代码。

#3


6  

At least in java, it's not voodoo programming at all. When you create an object in java using something like

至少在java中,它根本不是伏都教编程。当您使用类似的东西在java中创建一个对象时

Foo bar = new Foo();

you do two things: first, you create a reference to an object, and second, you create the Foo object itself. So long as that reference or another exists, the specific object can't be gc'd. however, when you assign null to that reference...

你做两件事:首先,你创建一个对象的引用,第二,你创建Foo对象本身。只要引用或其他引用存在,特定对象就不能被gc控制。但是,当您将null赋给该引用时……

bar = null ;

and assuming nothing else has a reference to the object, it's freed and available for gc the next time the garbage collector passes by.

假设没有其他对象的引用,那么下次垃圾收集器经过时,它将被释放并为gc可用。

#4


6  

Explicitly setting a reference to null instead of just letting the variable go out of scope, does not help the garbage collector, unless the object held is very large, where setting it to null as soon as you are done with is a good idea.

显式地将引用设置为null,而不是让变量超出范围,这对垃圾收集器没有帮助,除非对象非常大,在这种情况下,在您完成之后立即将其设置为null是一个好主意。

Generally setting references to null, mean to the READER of the code that this object is completely done with and should not be concerned about any more.

通常将引用设置为null,这意味着对这个对象已经完全完成的代码的读取者来说,不应该再关心了。

A similar effect can be achieved with by putting in an extra set of braces

同样的效果也可以通过增加一组括号来实现

{
  int l;
  {
    String bigThing = ....;
    l = bigThing.length();
  }
  ---
}

this allows the bigThing to be garbage collected right after leaving the nested braces.

这允许在离开嵌套的大括号后立即收集大数据。

#5


6  

Good article is today's coding horror.

好文章是今天的编码恐怖。

The way GC's work is by looking for objects that do not have any pointers to them, the area of their search is heap/stack and any other spaces they have. So if you set a variable to null, the actual object is now not pointed by anyone, and hence could be GC'd.

GC的工作方式是寻找没有指向它们的指针的对象,它们的搜索区域是堆/堆栈和它们拥有的任何其他空间。所以如果你将一个变量设置为null,那么实际的对象就不会被任何人指向,因此可能是GC。

But since the GC might not run at that exact instant, you might not actually be buying yourself anything. But if your method is fairly long (in terms of execution time) it might be worth it since you will be increasing your chances of GC collecting that object.

但是,由于GC可能不会立即运行,您可能不会为自己买任何东西。但是,如果您的方法相当长(在执行时间方面),它可能是值得的,因为您将增加GC收集该对象的机会。

The problem can also be complicated with code optimizations, if you never use the variable after you set it to null, it would be a safe optimization to remove the line that sets the value to null (one less instruction to execute). So you might not actually be getting any improvement.

代码优化也会使问题变得复杂,如果您在将变量设置为null之后从未使用该变量,那么删除将值设置为null的行(少执行一条指令)将是一个安全的优化。所以你可能没有得到任何改善。

So in summary, yes it can help, but it will not be deterministic.

总之,它是有帮助的,但不是确定性的。

#6


5  

It depends.

视情况而定。

Generally speaking shorter you keep references to your objects, faster they'll get collected.

一般来说,你对对象的引用越短,收集对象的速度就越快。

If your method takes say 2 seconds to execute and you don't need an object anymore after one second of method execution, it makes sense to clear any references to it. If GC sees that after one second, your object is still referenced, next time it might check it in a minute or so.

如果您的方法需要2秒执行,并且在执行了1秒的方法之后,您不再需要一个对象,那么清除任何对它的引用都是有意义的。如果GC在一秒钟后看到,您的对象仍然被引用,下一次它可能会在一分钟左右检查它。

Anyway, setting all references to null by default is to me premature optimization and nobody should do it unless in specific rare cases where it measurably decreases memory consuption.

无论如何,默认地将所有引用设置为null对我来说是不成熟的优化,任何人都不应该这样做,除非在特定的罕见情况下,它可以度量地减少内存占用。

#7


5  

public class JavaMemory {
    private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        {
            byte[] data = new byte[dataSize];
            //data = null;
        }

        byte[] data2 = new byte[dataSize];
    }

    public static void main(String[] args) {

        JavaMemory jmp = new JavaMemory();
        jmp.f();

    }

}

Above program throws OutOfMemoryError. If you uncomment data = null;, the OutOfMemoryError is solved. It is always good practice to set the unused variable to null

以上程序抛出OutOfMemoryError。如果取消注释数据= null,则解决了OutOfMemoryError。将未使用的变量设置为null总是很好的做法

#8


3  

I was working on a video conferencing application one time and noticed a huge huge huge difference in performance when I took the time to null references as soon as I didn't need the object anymore. This was in 2003-2004 and I can only imagine the GC has gotten even smarter since. In my case I had hundreds of objects coming and going out of scope every second, so I noticed the GC when it kicked in periodically. However after I made it a point to null objects the GC stopped pausing my application.

有一次,我正在开发一个视频会议应用程序,当我不再需要对象时,我花时间去空引用,发现性能有巨大的差异。这是在2003-2004年,我只能想象GC从那时起变得更聪明了。在我的例子中,每秒钟有数百个对象进出范围,所以我注意到GC周期性地启动。然而,当我将它设置为null对象后,GC停止暂停我的应用程序。

So it depends on what your doing...

这取决于你在做什么。

#9


2  

Yes.

是的。

From "The Pragmatic Programmer" p.292:

《实用程序员》第292页:

By setting a reference to NULL you reduce the number of pointers to the object by one ... (which will allow the garbage collector to remove it)

通过将引用设置为NULL,可以将指向对象的指针数量减少1个……(这将允许垃圾收集器删除它)

#10


1  

I assume the OP is referring to things like this:

我猜OP指的是这样的事情:

private void Blah()
{
    MyObj a;
    MyObj b;

    try {
        a = new MyObj();
        b = new MyObj;

        // do real work
    } finally {
        a = null;
        b = null;
    }
}

In this case, wouldn't the VM mark them for GC as soon as they leave scope anyway?

在这种情况下,VM不应该在它们离开作用域时就将它们标记为GC吗?

Or, from another perspective, would explicitly setting the items to null cause them to get GC'd before they would if they just went out of scope? If so, the VM may spend time GC'ing the object when the memory isn't needed anyway, which would actually cause worse performance CPU usage wise because it would be GC'ing more earlier.

或者,从另一个角度来看,是否会显式地将项设置为null,使它们在超出范围之前获得GC ?如果是这样,那么VM可能会在不需要内存的情况下花费时间GC对象,这实际上会导致性能更差的CPU使用率,因为GC会更早一些。

#11


0  

"It depends"

“看情况”

I do not know about Java but in .net (C#, VB.net...) it is usually not required to assign a null when you no longer require a object.

我不知道Java,但在。net (c#, VB.net…)中,当您不再需要对象时,通常不需要分配null。

However note that it is "usually not required".

但是请注意,它“通常不是必需的”。

By analyzing your code the .net compiler makes a good valuation of the life time of the variable...to accurately tell when the object is not being used anymore. So if you write obj=null it might actually look as if the obj is still being used...in this case it is counter productive to assign a null.

通过分析代码,.net编译器可以很好地评估变量的生命周期……准确地判断什么时候该对象不再被使用。所以如果你写obj=null它看起来好像obj还在用。在这种情况下,分配null是反生产的。

There are a few cases where it might actually help to assign a null. One example is you have a huge code that runs for long time or a method that is running in a different thread, or some loop. In such cases it might help to assign null so that it is easy for the GC to know its not being used anymore.

在一些情况下,它实际上可能有助于分配null。一个例子是,您有一个长时间运行的大型代码,或者一个在不同线程中运行的方法,或者某个循环。在这种情况下,它可以帮助分配null,这样GC就很容易知道它不再被使用了。

There is no hard & fast rule for this. Going by the above place null-assigns in your code and do run a profiler to see if it helps in any way. Most probably you might not see a benefit.

这没有硬性规定。通过上面的位置,在代码中分配null,并运行一个分析器,看看它是否有任何帮助。你可能看不到好处。

If it is .net code you are trying to optimize, then my experience has been that taking good care with Dispose and Finalize methods is actually more beneficial than bothering about nulls.

如果你想要优化的是。net代码,那么我的经验是,对Dispose和Finalize方法小心谨慎实际上比为nulls操心更有好处。

Some references on the topic:

关于这个主题的一些参考文献:

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx

#12


0  

Even if nullifying the reference were marginally more efficient, would it be worth the ugliness of having to pepper your code with these ugly nullifications? They would only be clutter and obscure the intent code that contains them.

即使使引用无效的效率稍微高一些,但是用这些丑陋的无效来替换代码是否值得?它们只会变得混乱,模糊包含它们的意图代码。

Its a rare codebase that has no better candidate for optimisation than trying to outsmart the Garbage collector (rarer still are developers who succeed in outsmarting it). Your efforts will most likely be better spent elsewhere instead, ditching that crufty Xml parser or finding some opportunity to cache computation. These optimisations will be easier to quantify and don't require you dirty up your codebase with noise.

这是一种罕见的代码基,没有比试图智胜垃圾收集器更好的优化候选者了(更罕见的是成功地智胜垃圾收集器的开发人员)。相反,您的努力很可能会花在其他地方,抛弃那个笨拙的Xml解析器,或者找到一些缓存计算的机会。这些优化将更容易量化,并且不需要你用噪音污染你的代码库。

#13


0  

In the future execution of your program, the values of some data members will be used to computer an output visible external to the program. Others might or might not be used, depending on future (And impossible to predict) inputs to the program. Other data members might be guaranteed not to be used. All resources, including memory, allocated to those unused data are wasted. The job of the garbage collector (GC) is to eliminate that wasted memory. It would be disastrous for the GC to eliminate something that was needed, so the algorithm used might be conservative, retaining more than the strict minimum. It might use heuristic optimizations to improve its speed, at the cost of retaining some items that are not actually needed. There are many potential algorithms the GC might use. Therefore it is possible that changes you make to your program, and which do not affect the correctness of your program, might nevertheless affect the operation of the GC, either making it run faster to do the same job, or to sooner identify unused items. So this kind of change, setting an unusdd object reference to null, in theory is not always voodoo.

在将来的程序执行中,一些数据成员的值将被用来计算程序外部可见的输出。另一些可能会被使用,也可能不会被使用,这取决于程序的未来(也不可能预测)输入。可以保证不使用其他数据成员。分配给那些未使用的数据的所有资源(包括内存)都被浪费了。垃圾收集器(GC)的工作是消除浪费的内存。对于GC来说,消除某些需要的东西将是灾难性的,因此所使用的算法可能是保守的,保留超过严格的最小值。它可能使用启发式优化来提高速度,代价是保留一些实际上不需要的项。GC可能使用许多潜在的算法。因此,您对您的程序所做的更改(不影响程序的正确性)可能仍然会影响GC的操作,或者使它运行得更快以完成相同的工作,或者更早地识别未使用的项。因此,这种改变,将unusdd对象引用设置为null,在理论上并不总是巫毒。

Is it voodoo? There are reportedly parts of the Java library code that do this. The writers of that code are much better than average programmers and either know, or cooperate with, programmers who know details of the garbage collector implementations. So that suggests there is sometimes a benefit.

伏都教吗?据报道,Java库代码中有一些部分可以做到这一点。该代码的作者要比普通程序员好得多,他们要么知道,要么与了解垃圾收集器实现细节的程序员合作。因此,这就意味着有时会有好处。

#1


55  

Typically, no.

通常,没有。

But like all things: it depends. The GC in Java these days is VERY good and everything should be cleaned up very shortly after it is no longer reachable. This is just after leaving a method for local variables, and when a class instance is no longer referenced for fields.

但就像所有事情一样:这要看情况。现在Java中的GC非常好,在不能再访问之后,应该很快清理所有东西。这是在为局部变量留下一个方法之后,当类实例不再被字段引用时。

You only need to explicitly null if you know it would remain referenced otherwise. For example an array which is kept around. You may want to null the individual elements of the array when they are no longer needed.

如果您知道它将继续被引用,您只需要显式为空。例如,一个保存在周围的数组。当不再需要数组的各个元素时,您可能希望它们为空。

For example, this code from ArrayList:

例如,来自ArrayList的代码:

public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
             numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

Also, explicitly nulling an object will not cause an object to be collected any sooner than if it just went out of scope naturally as long as no references remain.

此外,显式地取消对象并不会导致对象被收集的时间比只要没有引用就自然地超出范围更短。

Both:

两个:

void foo() {
   Object o = new Object();
   /// do stuff with o
}

and:

和:

void foo() {
   Object o = new Object();
   /// do stuff with o
   o = null;
}

Are functionally equivalent.

在功能上是等价的。

#2


9  

In my experience, more often than not, people null out references out of paranoia not out of necessity. Here is a quick guideline:

在我的经验中,通常情况下,人们出于偏执而不是出于需要而放弃了引用。这里有一个简单的指导方针:

  1. If object A references object B and you no longer need this reference and object A is not eligible for garbage collection then you should explicitly null out the field. There is no need to null out a field if the enclosing object is getting garbage collected anyway. Nulling out fields in a dispose() method is almost always useless.

    如果对象A引用对象B,而您不再需要该引用,并且对象A不适合进行垃圾收集,那么您应该显式地将字段空出。如果封装对象正在收集垃圾,则不需要空出字段。在dispose()方法中取消字段几乎总是无用的。

  2. There is no need to null out object references created in a method. They will get cleared automatically once the method terminates. The exception to this rule is if you're running in a very long method or some massive loop and you need to ensure that some references get cleared before the end of the method. Again, these cases are extremely rare.

    不需要空出方法中创建的对象引用。一旦方法终止,它们将被自动清除。这个规则的例外是,如果您运行的是一个非常长的方法或一个大的循环,您需要确保在方法结束之前有一些引用被清除。同样,这种情况非常罕见。

I would say that the vast majority of the time you will not need to null out references. Trying to outsmart the garbage collector is useless. You will just end up with inefficient, unreadable code.

我想说,在绝大多数情况下,您不需要空出引用。试图智取垃圾收集器是没有用的。您最终会得到低效的、不可读的代码。

#3


6  

At least in java, it's not voodoo programming at all. When you create an object in java using something like

至少在java中,它根本不是伏都教编程。当您使用类似的东西在java中创建一个对象时

Foo bar = new Foo();

you do two things: first, you create a reference to an object, and second, you create the Foo object itself. So long as that reference or another exists, the specific object can't be gc'd. however, when you assign null to that reference...

你做两件事:首先,你创建一个对象的引用,第二,你创建Foo对象本身。只要引用或其他引用存在,特定对象就不能被gc控制。但是,当您将null赋给该引用时……

bar = null ;

and assuming nothing else has a reference to the object, it's freed and available for gc the next time the garbage collector passes by.

假设没有其他对象的引用,那么下次垃圾收集器经过时,它将被释放并为gc可用。

#4


6  

Explicitly setting a reference to null instead of just letting the variable go out of scope, does not help the garbage collector, unless the object held is very large, where setting it to null as soon as you are done with is a good idea.

显式地将引用设置为null,而不是让变量超出范围,这对垃圾收集器没有帮助,除非对象非常大,在这种情况下,在您完成之后立即将其设置为null是一个好主意。

Generally setting references to null, mean to the READER of the code that this object is completely done with and should not be concerned about any more.

通常将引用设置为null,这意味着对这个对象已经完全完成的代码的读取者来说,不应该再关心了。

A similar effect can be achieved with by putting in an extra set of braces

同样的效果也可以通过增加一组括号来实现

{
  int l;
  {
    String bigThing = ....;
    l = bigThing.length();
  }
  ---
}

this allows the bigThing to be garbage collected right after leaving the nested braces.

这允许在离开嵌套的大括号后立即收集大数据。

#5


6  

Good article is today's coding horror.

好文章是今天的编码恐怖。

The way GC's work is by looking for objects that do not have any pointers to them, the area of their search is heap/stack and any other spaces they have. So if you set a variable to null, the actual object is now not pointed by anyone, and hence could be GC'd.

GC的工作方式是寻找没有指向它们的指针的对象,它们的搜索区域是堆/堆栈和它们拥有的任何其他空间。所以如果你将一个变量设置为null,那么实际的对象就不会被任何人指向,因此可能是GC。

But since the GC might not run at that exact instant, you might not actually be buying yourself anything. But if your method is fairly long (in terms of execution time) it might be worth it since you will be increasing your chances of GC collecting that object.

但是,由于GC可能不会立即运行,您可能不会为自己买任何东西。但是,如果您的方法相当长(在执行时间方面),它可能是值得的,因为您将增加GC收集该对象的机会。

The problem can also be complicated with code optimizations, if you never use the variable after you set it to null, it would be a safe optimization to remove the line that sets the value to null (one less instruction to execute). So you might not actually be getting any improvement.

代码优化也会使问题变得复杂,如果您在将变量设置为null之后从未使用该变量,那么删除将值设置为null的行(少执行一条指令)将是一个安全的优化。所以你可能没有得到任何改善。

So in summary, yes it can help, but it will not be deterministic.

总之,它是有帮助的,但不是确定性的。

#6


5  

It depends.

视情况而定。

Generally speaking shorter you keep references to your objects, faster they'll get collected.

一般来说,你对对象的引用越短,收集对象的速度就越快。

If your method takes say 2 seconds to execute and you don't need an object anymore after one second of method execution, it makes sense to clear any references to it. If GC sees that after one second, your object is still referenced, next time it might check it in a minute or so.

如果您的方法需要2秒执行,并且在执行了1秒的方法之后,您不再需要一个对象,那么清除任何对它的引用都是有意义的。如果GC在一秒钟后看到,您的对象仍然被引用,下一次它可能会在一分钟左右检查它。

Anyway, setting all references to null by default is to me premature optimization and nobody should do it unless in specific rare cases where it measurably decreases memory consuption.

无论如何,默认地将所有引用设置为null对我来说是不成熟的优化,任何人都不应该这样做,除非在特定的罕见情况下,它可以度量地减少内存占用。

#7


5  

public class JavaMemory {
    private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        {
            byte[] data = new byte[dataSize];
            //data = null;
        }

        byte[] data2 = new byte[dataSize];
    }

    public static void main(String[] args) {

        JavaMemory jmp = new JavaMemory();
        jmp.f();

    }

}

Above program throws OutOfMemoryError. If you uncomment data = null;, the OutOfMemoryError is solved. It is always good practice to set the unused variable to null

以上程序抛出OutOfMemoryError。如果取消注释数据= null,则解决了OutOfMemoryError。将未使用的变量设置为null总是很好的做法

#8


3  

I was working on a video conferencing application one time and noticed a huge huge huge difference in performance when I took the time to null references as soon as I didn't need the object anymore. This was in 2003-2004 and I can only imagine the GC has gotten even smarter since. In my case I had hundreds of objects coming and going out of scope every second, so I noticed the GC when it kicked in periodically. However after I made it a point to null objects the GC stopped pausing my application.

有一次,我正在开发一个视频会议应用程序,当我不再需要对象时,我花时间去空引用,发现性能有巨大的差异。这是在2003-2004年,我只能想象GC从那时起变得更聪明了。在我的例子中,每秒钟有数百个对象进出范围,所以我注意到GC周期性地启动。然而,当我将它设置为null对象后,GC停止暂停我的应用程序。

So it depends on what your doing...

这取决于你在做什么。

#9


2  

Yes.

是的。

From "The Pragmatic Programmer" p.292:

《实用程序员》第292页:

By setting a reference to NULL you reduce the number of pointers to the object by one ... (which will allow the garbage collector to remove it)

通过将引用设置为NULL,可以将指向对象的指针数量减少1个……(这将允许垃圾收集器删除它)

#10


1  

I assume the OP is referring to things like this:

我猜OP指的是这样的事情:

private void Blah()
{
    MyObj a;
    MyObj b;

    try {
        a = new MyObj();
        b = new MyObj;

        // do real work
    } finally {
        a = null;
        b = null;
    }
}

In this case, wouldn't the VM mark them for GC as soon as they leave scope anyway?

在这种情况下,VM不应该在它们离开作用域时就将它们标记为GC吗?

Or, from another perspective, would explicitly setting the items to null cause them to get GC'd before they would if they just went out of scope? If so, the VM may spend time GC'ing the object when the memory isn't needed anyway, which would actually cause worse performance CPU usage wise because it would be GC'ing more earlier.

或者,从另一个角度来看,是否会显式地将项设置为null,使它们在超出范围之前获得GC ?如果是这样,那么VM可能会在不需要内存的情况下花费时间GC对象,这实际上会导致性能更差的CPU使用率,因为GC会更早一些。

#11


0  

"It depends"

“看情况”

I do not know about Java but in .net (C#, VB.net...) it is usually not required to assign a null when you no longer require a object.

我不知道Java,但在。net (c#, VB.net…)中,当您不再需要对象时,通常不需要分配null。

However note that it is "usually not required".

但是请注意,它“通常不是必需的”。

By analyzing your code the .net compiler makes a good valuation of the life time of the variable...to accurately tell when the object is not being used anymore. So if you write obj=null it might actually look as if the obj is still being used...in this case it is counter productive to assign a null.

通过分析代码,.net编译器可以很好地评估变量的生命周期……准确地判断什么时候该对象不再被使用。所以如果你写obj=null它看起来好像obj还在用。在这种情况下,分配null是反生产的。

There are a few cases where it might actually help to assign a null. One example is you have a huge code that runs for long time or a method that is running in a different thread, or some loop. In such cases it might help to assign null so that it is easy for the GC to know its not being used anymore.

在一些情况下,它实际上可能有助于分配null。一个例子是,您有一个长时间运行的大型代码,或者一个在不同线程中运行的方法,或者某个循环。在这种情况下,它可以帮助分配null,这样GC就很容易知道它不再被使用了。

There is no hard & fast rule for this. Going by the above place null-assigns in your code and do run a profiler to see if it helps in any way. Most probably you might not see a benefit.

这没有硬性规定。通过上面的位置,在代码中分配null,并运行一个分析器,看看它是否有任何帮助。你可能看不到好处。

If it is .net code you are trying to optimize, then my experience has been that taking good care with Dispose and Finalize methods is actually more beneficial than bothering about nulls.

如果你想要优化的是。net代码,那么我的经验是,对Dispose和Finalize方法小心谨慎实际上比为nulls操心更有好处。

Some references on the topic:

关于这个主题的一些参考文献:

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx

#12


0  

Even if nullifying the reference were marginally more efficient, would it be worth the ugliness of having to pepper your code with these ugly nullifications? They would only be clutter and obscure the intent code that contains them.

即使使引用无效的效率稍微高一些,但是用这些丑陋的无效来替换代码是否值得?它们只会变得混乱,模糊包含它们的意图代码。

Its a rare codebase that has no better candidate for optimisation than trying to outsmart the Garbage collector (rarer still are developers who succeed in outsmarting it). Your efforts will most likely be better spent elsewhere instead, ditching that crufty Xml parser or finding some opportunity to cache computation. These optimisations will be easier to quantify and don't require you dirty up your codebase with noise.

这是一种罕见的代码基,没有比试图智胜垃圾收集器更好的优化候选者了(更罕见的是成功地智胜垃圾收集器的开发人员)。相反,您的努力很可能会花在其他地方,抛弃那个笨拙的Xml解析器,或者找到一些缓存计算的机会。这些优化将更容易量化,并且不需要你用噪音污染你的代码库。

#13


0  

In the future execution of your program, the values of some data members will be used to computer an output visible external to the program. Others might or might not be used, depending on future (And impossible to predict) inputs to the program. Other data members might be guaranteed not to be used. All resources, including memory, allocated to those unused data are wasted. The job of the garbage collector (GC) is to eliminate that wasted memory. It would be disastrous for the GC to eliminate something that was needed, so the algorithm used might be conservative, retaining more than the strict minimum. It might use heuristic optimizations to improve its speed, at the cost of retaining some items that are not actually needed. There are many potential algorithms the GC might use. Therefore it is possible that changes you make to your program, and which do not affect the correctness of your program, might nevertheless affect the operation of the GC, either making it run faster to do the same job, or to sooner identify unused items. So this kind of change, setting an unusdd object reference to null, in theory is not always voodoo.

在将来的程序执行中,一些数据成员的值将被用来计算程序外部可见的输出。另一些可能会被使用,也可能不会被使用,这取决于程序的未来(也不可能预测)输入。可以保证不使用其他数据成员。分配给那些未使用的数据的所有资源(包括内存)都被浪费了。垃圾收集器(GC)的工作是消除浪费的内存。对于GC来说,消除某些需要的东西将是灾难性的,因此所使用的算法可能是保守的,保留超过严格的最小值。它可能使用启发式优化来提高速度,代价是保留一些实际上不需要的项。GC可能使用许多潜在的算法。因此,您对您的程序所做的更改(不影响程序的正确性)可能仍然会影响GC的操作,或者使它运行得更快以完成相同的工作,或者更早地识别未使用的项。因此,这种改变,将unusdd对象引用设置为null,在理论上并不总是巫毒。

Is it voodoo? There are reportedly parts of the Java library code that do this. The writers of that code are much better than average programmers and either know, or cooperate with, programmers who know details of the garbage collector implementations. So that suggests there is sometimes a benefit.

伏都教吗?据报道,Java库代码中有一些部分可以做到这一点。该代码的作者要比普通程序员好得多,他们要么知道,要么与了解垃圾收集器实现细节的程序员合作。因此,这就意味着有时会有好处。