将Java对象设置为null是否可以做任何事情?
我正在浏览一些旧书,并findPeter Hagger的“Practical Java”的副本。 在性能部分中,build议在不再需要时将对象引用设置为null
。
在Java中,是否将对象引用设置为null
提高性能或垃圾收集效率? 如果是这样,这是一个什么情况? 容器类? 对象组成? 匿名内部类?
我经常在代码中看到这个。 这是现在已经过时的编程build议还是仍然有用?
这在一定程度上取决于你何时想引用参考。
如果你有一个对象链A-> B-> C,那么一旦A不可达,A,B和C都将有资格进行垃圾回收(假设没有别的指向B或C)。 例如,没有必要明确地将参考A-> B或B-> C设置为空,并且从未有任何需要。
除此之外,大多数情况下问题并不真正出现,因为实际上你正在处理集合中的对象。 您通常应该总是考虑通过调用适当的remove()方法来从列表,地图等中移除对象。
曾经有一些build议将引用设置为null的情况,特别是在一个很长的范围内,一个内存密集型的对象在部分范围内不再使用 。 例如:
{ BigObject obj = ... doSomethingWith(obj); obj = null; <-- explicitly set to null doSomethingElse(); }
这里的基本原理是,因为obj仍然在范围之内,所以没有显式的引用的引用,直到doSomethingElse()方法完成之后才会变成垃圾回收。 这是现代JVM可能不再适用的build议:事实certificate,JIT编译器可以解决给定的本地对象引用不再使用的问题。
不,这不是过时的build议。 悬而未决的引用仍然是一个问题,尤其是如果你使用预先分配的数组来实现可扩展的数组容器( ArrayList
或类似的)。 列表中“超过逻辑”大小的元素应该被清除,否则就不会被释放。
请参阅有效Java第2版,第6项:消除过时的对象引用。
实例字段,数组元素
如果有一个对象的引用,它不能被垃圾回收。 特别是如果这个对象(以及它后面的整个图)很大,那么只有一个引用停止垃圾回收,而且这个引用不再需要,这是一个不幸的情况。
病态的情况是对整个XML DOM树(用于configuration它),未注册的MBean或从未部署的Web应用程序中单个引用一个对象,从而阻止整个类加载器被卸载。
所以除非你确定持有引用的对象本身将被垃圾回收(或者甚至是垃圾回收),否则你应该清空你不再需要的所有东西。
范围variables:
如果你正在考虑在它的作用域结束之前设置一个局部variables为null,这样它可以被垃圾回收器回收,并将其标记为“从现在开始不可用”,你应该考虑把它放在一个更有限的范围内。
{ BigObject obj = ... doSomethingWith(obj); obj = null; // <-- explicitly set to null doSomethingElse(); }
变
{ { BigObject obj = ... doSomethingWith(obj); } // <-- obj goes out of scope doSomethingElse(); }
代码的易读性通常很差,平坦的示波器也是不好的。 引入私有方法来解决这个问题并不是闻所未闻的。
在限制内存的环境中(如手机),这可能是有用的。 通过设置null,objetc不需要等待variables超出范围才能被gc'd。
然而,对于日常的节目来说,这不应该成为规则,除非Chris Jester-Young所引用的特殊情况。
首先,这并不意味着你将对象设置为null。 我在下面解释一下:
List list1=new ArrayList(); List list2=list1;
在上面的代码段中,我们正在做的是,实际上我们正在创build存储在内存中的ArrayList对象的对象引用variables名list1。 所以list1引用该对象,它不仅仅是一个variables。 而在第二行代码中,我们将list1的引用复制到list2中。 所以现在回到你的问题,如果我这样做:
list1=null;
这意味着list1不再引用存储在内存中的任何对象,所以list2也没有任何可引用的东西。 所以如果你检查list2的大小:
list2.size(); //it gives you 0
所以这里的垃圾回收器的概念到了,它说: “你无需担心释放对象所拥有的内存,当我发现它不再用于程序和JVM将pipe理我时,我会这样做。
我希望清楚这个概念。