在java中什么是过时的引用

  • 本文关键字:过时 引用 java java
  • 更新时间 :
  • 英文 :


我正在阅读《高效Java》一书,书中说消除过时的引用是避免内存泄漏的最佳方法之一。根据下面的程序,通过执行->elements[size]=null;它消除了该程序中过时的引用。我的问题是做elements[size]=null;有什么好处;。任何其他程序都可以使用该释放的内存位置?还是垃圾收集?根据我的理解,数组已经为其大小分配了内存。即使我们做元素[size]=null;在执行elements=null;之前,任何人都不能使用释放的内存位置;。请有人告诉我做elements[size]=null有什么好处;在这里

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}

我的问题是做elements[size]=null;的优点是什么;。

这里的过时引用是指程序不再需要的对象引用
您希望不必要的对象可以自由使用,只消耗程序所需的内存。一般来说,这样做是为了当前应用程序的良好工作。

任何其他程序都可以使用释放的内存位置?

理论上是的,但这也取决于使用的JVM内存选项。你通常不会关注它。

CCD_ 1和CCD_。

在本书中,elements是一个班级的结构实习生
其想法是,在执行一些删除操作后,阵列中的某些元素可能已过时,不再需要。

第一个(elements[size] = null)将使位于size索引处的数组元素的对象在没有其他对象引用的情况下有资格成为GC
但第二个(elements = null)要多得多。如果没有其他对象引用它,它将使数组的所有元素都有资格成为GC

我们必须区分两种情况:

  1. 外部对象以某种方式被"拆除",因此它关闭了任何打开的资源,并"自愿"释放了它所引用的所有对象。这只是告诉jvm相应引用已"消失"的明确方式。您使gc更容易理解:相应的对象有资格进行垃圾收集。当然,只有在其他地方没有对同一对象的其他引用的情况下,才会有这种效果。除此之外:这并不是真正需要的,jvm/gc当然必须能够自己检测任何符合条件的对象
  2. 但是,对于存在时间较长的引用,在该时间段内指向不同的对象,取消引用是有意义的。就像容器一样,比如底层示例中的堆栈类。容器在被"移除"时必须忘记其引用的对象。否则会造成内存泄漏

这里发生了什么

让我们想象一下,elements是一个20个元素的Object数组(elements = new Object[20];),并且已经填充了18个elements[size] = null0实例,其余两个位置为空。

因此,堆现在包含18个BigInteger实例和一个20个元素的Object[]数组。垃圾收集器不会回收这些实例中的任何一个,这没关系,因为您稍后很可能会使用它们(通过pop()方法)。

现在调用pop()方法来获取最近添加到数组中的BigInteger。假设你只想打印它,然后忘记它,所以在你的整个应用程序中,这个数字不再需要了,你会期望垃圾收集器回收它。但除非你执行空分配,否则这不会发生

elements[size] = null; // Eliminate obsolete reference

为什么

只要您将对对象的引用存储在某个可访问的位置,垃圾收集器就会认为您以后仍然需要该对象。

只要elements[17]仍然引用BigInteger,它就可能被您的程序访问,因此无法回收。如果elements[17]指向null,则过去存在的BigInteger将无法再通过elements = null;0访问,并且可以由垃圾收集器回收(如果您的代码中没有其他部分仍在使用它)。

结论

只有当你有一个包含胖对象的长寿命存储结构,并且你可以在某个时间点告诉你不再需要其中一个存储对象时,才值得考虑"过时的引用"。由于您不再需要该对象,现在可以使用null重新分配存储,然后GC不再认为您仍然需要该对象并能够回收存储空间。

最新更新