5
ArrayList<Object> foo;
Object[] bar;

典型的终结者会做

foo = null;
bar = null;

我的问题是,ArrayList 会调用一个终结器,它将它持有的任何指针设置为空,还是我必须逐步完成列表

for(i=1; i<foo.size(); i++) foo.set(i,null); ???

另一个问题:对于一个数组,我是否需要将它的任何内容设置为空,比如

for(i=1; i<bar.length; i++) bar[i] = null;

或者是否足以丢弃整个内存块并且之后其中的任何指针超出范围?

对不起,如果这个问题很愚蠢。

在阅读了我发现的答案后,您自己没有什么可以实现的。

一些消息来源表明,如果发生这样的事情(吃内存的应用程序),这是设计不当。

我的核心问题是:经常做

struct = new LargeStructure();

这会耗尽内存吗?

或者这是否只需要其中一个结构的内存?

顺便说一句:问题出现在运行 tomcat 的 webapp 中,并且只有一个会话处于活动状态,它将所描述的指针作为会话变量保存。

4

4 回答 4

4

当不再引用所有对象时,垃圾收集器将自动获得 GC 资格。你不必担心。如果您将数组引用设置为null,那么如果没有其他对数组对象的实时引用,则数组对象本身就有资格进行 GC,如果不再有对数组对象的实时引用,则数组元素将有资格进行 GC。

根据文档

protected void finalize() throws Throwable

当垃圾收集确定不再有对该对象的引用时,由对象上的垃圾收集器调用。子类覆盖 finalize 方法以释放系统资源或执行其他清理。

finalize()方法将在 GC 检测到对象不再可达之后,在它实际回收对象使用的内存之前调用。如果对象永远不会变得不可访问,或者 GC 没有运行,那么finalize()可能永远不会被调用。

您可以尝试finalize()通过调用System.runFinalization()来强制 JVM 调用:

运行任何等待终结的对象的终结方法。

调用此方法表明 Java 虚拟机花费精力运行已发现已丢弃但尚未运行其 finalize 方法的对象的 finalize 方法。当控制从方法调用返回时,Java 虚拟机已尽最大努力完成所有未完成的终结。

于 2013-06-15T16:06:34.807 回答
1

从理论上讲,终结器可以让您在对象被垃圾收集回收之前对它们执行最后一分钟的任务。然而在实践中,不能保证它们会被调用,所以它们不是很有用。

于 2013-06-15T16:17:45.403 回答
0

您不必null在终结器块中设置对象的引用。终结器通常用于最后机会资源关闭,这不是一个好习惯,但终结器可以为您提供资源管理的安全网。

于 2013-06-15T16:07:05.800 回答
0

我的问题是,ArrayList 会调用一个终结器,它将它持有的任何指针设置为空,还是我必须逐步完成列表

ArrayList不会调用终结器,终结器线程会这样做,但您不必担心。此外,您不必自己查看列表并最终确定您的元素。Java Garbage Collector 将为您找出一个并拾取这些对象,只要它们没有在代码中的其他任何地方引用。

另一个问题:对于一个数组,我是否需要将它的任何内容设置为空,比如

不,和上面一样。要记住的重要一点是,如果您希望垃圾收集器将其拾取,则您没有引用数组中的任何值或数组本身。

于 2013-06-15T16:22:29.300 回答