将 Java 对象设置为 null 有什么作用吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/850878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does setting Java objects to null do anything anymore?
提问by sal
I was browsing some old books and found a copy of "Practical Java" by Peter Hagger. In the performance section, there is a recommendation to set object references to null
when no longer needed.
我在浏览一些旧书时发现了一份 Peter Hagger 的“实用 Java”。在性能部分,建议null
在不再需要时设置对象引用。
In Java, does setting object references to null
improve performance or garbage collection efficiency? If so, in what cases is this an issue? Container classes? Object composition? Anonymous inner classes?
在Java中,设置对象引用是为了null
提高性能还是垃圾回收效率?如果是这样,在什么情况下这是一个问题?容器类?对象组成?匿名内部类?
I see this in code pretty often. Is this now obsolete programming advice or is it still useful?
我经常在代码中看到这一点。这是现在已经过时的编程建议还是仍然有用?
采纳答案by Neil Coffey
It depends a bit on when you were thinking of nulling the reference.
这在一定程度上取决于您何时考虑将引用归零。
If you have an object chain A->B->C, then once A is not reachable, A, B and C will all be eligible for garbage collection (assuming nothing else is referring to either B or C). There's no need, and never has been any need, to explicitly set references A->B or B->C to null, for example.
如果您有一个对象链 A->B->C,那么一旦 A 不可访问,A、B 和 C 都将有资格进行垃圾回收(假设没有其他内容指的是 B 或 C)。例如,没有必要也从来没有必要将引用 A->B 或 B->C 显式设置为 null。
Apart from that, most of the time the issue doesn't really arise, because in reality you're dealing with objects in collections. You should generally always be thinking of removing objects from lists, maps etc by calling the appropiate remove() method.
除此之外,大多数时候问题并没有真正出现,因为实际上您正在处理集合中的对象。您通常应该始终考虑通过调用适当的 remove() 方法从列表、地图等中删除对象。
The case where there used to besome advice to set references to null was specifically in a long scope where a memory-intensive object ceased to be used partway through the scope. For example:
其中存在的情况下使用的是一些建议以空集的引用被具体地在长范围,其中一个存储器密集型对象不再是通过使用范围的中途。例如:
{
BigObject obj = ...
doSomethingWith(obj);
obj = null; <-- explicitly set to null
doSomethingElse();
}
The rationale here was that because objis still in scope, then without the explicit nulling of the reference, it does not become garbage collectable until after the doSomethingElse()method completes. And this is the advice that probably no longer holds on modern JVMs: it turns out that the JIT compiler can work out at what point a given local object reference is no longer used.
这里的基本原理是,因为obj仍在范围内,所以如果没有显式地将引用清空,它在doSomethingElse()方法完成之前不会成为垃圾收集。这是现代 JVM 可能不再适用的建议:事实证明,JIT 编译器可以确定在什么时候不再使用给定的本地对象引用。
回答by Chris Jester-Young
No, it's not obsolete advice. Dangling references are still a problem, especially if you're, say, implementing an expandable array container (ArrayList
or the like) using a pre-allocated array. Elements beyond the "logical" size of the list should be nulled out, or else they won't be freed.
不,这不是过时的建议。悬空引用仍然是一个问题,尤其是当您ArrayList
使用预分配数组实现可扩展数组容器(或类似容器)时。超出列表“逻辑”大小的元素应该被清除,否则它们将不会被释放。
See Effective Java 2nd ed, Item 6: Eliminate Obsolete Object References.
请参阅 Effective Java 第二版,第 6 项:消除过时的对象引用。
回答by besen
In memory restrictive environments (e.g. cellphones) this can be useful. By setting null, the objetc don't need to wait the variable to get out of scope to be gc'd.
在内存受限的环境(例如手机)中,这可能很有用。通过设置 null,objetc 不需要等待变量超出范围被 gc'd。
For the everyday programming, however, this shouldn't be the rule, except in special cases like the one Chris Jester-Young cited.
然而,对于日常编程,这不应该成为规则,除非像 Chris Jester-Young 引用的那种特殊情况。
回答by Thilo
Instance fields, array elements
实例字段、数组元素
If there is a reference to an object, it cannot be garbage collected. Especially if that object (and the whole graph behind it) is big, there is only one reference that is stopping garbage collection, and that reference is not really needed anymore, that is an unfortunate situation.
如果存在对对象的引用,则不能对其进行垃圾回收。特别是如果该对象(及其背后的整个图)很大,则只有一个引用停止垃圾收集,并且不再真正需要该引用,这是一种不幸的情况。
Pathological cases are the object that retains an unnessary instance to the whole XML DOM tree that was used to configure it, the MBean that was not unregistered, or the single reference to an object from an undeployed web application that prevents a whole classloader from being unloaded.
病态情况是对象保留了用于配置它的整个 XML DOM 树的不必要实例,未注销的 MBean,或来自未部署的 Web 应用程序的对象的单个引用,从而阻止了整个类加载器被卸载.
So unless you are sure that the object that holds the reference itself will be garbage collected anyway (or even then), you should null out everything that you no longer need.
因此,除非您确定持有引用本身的对象无论如何都会被垃圾回收(甚至那时),否则您应该将不再需要的所有内容都归零。
Scoped variables:
范围变量:
If you are considering setting a local variable to null before the end of its scope , so that it can be reclaimed by the garbage collector and to mark it as "unusable from now on", you should consider putting it in a more limited scope instead.
如果您正在考虑在其作用域结束之前将局部变量设置为 null,以便垃圾收集器可以回收它并将其标记为“从现在起无法使用”,则应考虑将其置于更有限的作用域中.
{
BigObject obj = ...
doSomethingWith(obj);
obj = null; // <-- explicitly set to null
doSomethingElse();
}
becomes
变成
{
{
BigObject obj = ...
doSomethingWith(obj);
} // <-- obj goes out of scope
doSomethingElse();
}
Long, flat scopes are generally bad for legibility of the code, too. Introducing private methods to break things up just for that purpose is not unheard of, too.
长而扁平的范围通常也不利于代码的易读性。为了这个目的而引入私有方法来分解事物也并非闻所未闻。
回答by Aman Goel
Firstly, It does not mean anything that you are setting a object to null
. I explain it below:
首先,这并不意味着您将对象设置为null
. 我解释如下:
List list1 = new ArrayList();
List list2 = list1;
In above code segment we are creating the object reference variable name list1
of ArrayList
object that is stored in the memory. So list1
is referring that object and it nothing more than a variable. And in the second line of code we are copying the reference of list1
to list2
. So now going back to your question if I do:
在上面的代码段中,我们正在创建存储在内存中list1
的ArrayList
对象的对象引用变量名称。list1
引用该对象也是如此,它只不过是一个变量。在第二行代码中,我们复制了list1
to的引用list2
。所以现在回到你的问题,如果我这样做:
list1 = null;
that means list1
is no longer referring any object that is stored in the memory so list2
will also having nothing to refer. So if you check the size of list2
:
这意味着list1
不再引用存储在内存中的任何对象,因此list2
也将没有任何可引用的对象。因此,如果您检查 的大小list2
:
list2.size(); //it gives you 0
So here the concept of garbage collector arrives which says ?you nothing to worry about freeing the memory that is hold by the object, I will do that when I find that it will no longer used in program and JVM will manage me.?
所以这里垃圾收集器的概念到来了,它说?你不用担心释放对象持有的内存,当我发现它不再在程序中使用并且JVM会管理我时,我会这样做。?
I hope it clear the concept.
我希望它清楚这个概念。