在什么情况下java中显式nulling有用.它是否以任何方式通过使对象无法访问或某些东西来帮助垃圾收集器?它被认为是一种好习惯吗?
在Java中,如果您有一个非常长时间运行的方法,它可以提供帮助,并且对对象的唯一引用是通过局部变量.当您不再需要它时,将该局部变量设置为null(但是当该方法将继续运行很长时间时)可以帮助GC.(在C#中,这很少有用,因为GC会考虑"最后可能的使用".这种优化可能会让它在Java中出现一段时间 - 我不知道.)
同样,如果您有一个成员字段引用一个对象而您不再需要它,则可以通过将该字段设置为null来帮助GC.
然而,根据我的经验,做这些事情中的任何一个实际上很少有用,并且它会使代码变得更加混乱.很少有方法真正运行很长时间,将变量设置为null实际上与您希望方法实现的内容无关.当你不需要的时候这样做是不好的做法,如果你确实需要,你应该看看重构是否可以改善你的设计.(你的方法或类型可能做得太多了.)
请注意,将变量设置为null完全是被动的 - 它不会通知垃圾收集器可以收集对象,它只是避免垃圾收集器将该引用视为下次保持对象存活的原因(GC)运行.
通常不需要(当然可以依赖于VM实现).但是,如果您有这样的事情:
private static final Mapfoo;
然后在地图中有不再需要的项目,它们将不具备垃圾收集的条件,因此您需要明确删除它们.有很多这种情况(事件监听器是另一个可能发生这种情况的领域).
但做这样的事情:
void foo() { Object o; // use o o = null; // don't bother doing this, it isn't going to help }
编辑(忘了提这个):
如果您正在使用它,您应该会发现您声明的90-95%的变量可以是最终的.最终变量不能改变它指向的内容(或者它的基元值是什么).在变量是最终的大多数情况下,在方法执行时接收不同的值将是错误(错误).
如果您希望能够在使用后将变量设置为null,则它不能是最终的,这意味着您有更大的机会在代码中创建错误.
我发现它有用的一个特例是当你有一个非常大的对象,并想要用另一个大对象替换它.例如,查看以下代码:
BigObject bigObject = new BigObject(); // ... bigObject = new BigObject(); // line 3
如果BigObject的实例太大而你在堆中只能有一个这样的实例,那么第3行将因OutOfMemoryError而失败,因为在第3行的赋值指令完成之前,第1个实例无法释放,这显然是在第2个实例之后准备好了.
现在,如果在第3行之前将bigObject设置为null:
bigObject = null; bigObject = new BigObject(); // line 3
在构建第二个实例期间,当JVM用完堆时,可以释放第一个实例.
从"Effective Java":使用它来消除过时的对象引用.否则会导致内存泄漏,这可能很难调试.
public Object pop(){ if(size == 0) throw new EmptyStatckException(); Object result = elements[--size]; elements[size] = null; //Eliminate Object reference return result; }