2

假设我正在删除一个名为“Enemy”的“死”对象。

使用这样的东西:

for(int i = 0; i < enemies.size(); i++)
    {
    Enemy en = (Enemy) enemies.get(i);
    if(en.getVisible() == true)
        en.update();
    else
        enemies.remove(i);
    }

对象从 ArrayList 中删除后是否会被删除?还是“应该”?我以前主要做 C++ 代码,垃圾收集让我很困惑。

有什么方法可以查看垃圾收集器是否正在删除对象?

谢谢

4

5 回答 5

1

如果您从 ArrayList 中删除一个对象,并且该对象没有任何其他引用,那么它将是垃圾收集器的“合格”。之后,您不必担心将其从堆中删除:JVM 会通过自动垃圾收集器来完成此操作。

于 2013-03-27T05:43:01.363 回答
1

我真的很喜欢看到 C/C++ 和 Java 的整个垃圾收集惨败的反面。Java 有自己的垃圾收集器,您无需担心内存管理 - .remove() 就足够了。

于 2013-03-27T05:40:43.080 回答
0

我认为这取决于您如何输入对象。如果你将它保存在其他地方,它应该仍然存在,但是如果你直接将它添加到 arrayList 它可能是垃圾。

PS您的代码需要更正

enemies.remove(i);
enemies.remove(i--);
于 2013-03-27T05:43:04.307 回答
0

接受我关于ConcurrentModificationException回来的评论。你不会得到它,但你的循环仍然不正确。看一看:

List<String> list = new ArrayList<String>(Arrays.asList("A","B","C","D"));
for (int i = 0; i < list.size(); i++) {
    String s = list.get(i);
    if ("B".equals(s) || "C".equals(s)) list.remove(i);
}
System.out.println(list);

输出:

[A, C, D]

C由于i总是增加和跳过元素,因此不会被删除。

于 2013-03-27T05:53:37.843 回答
0

在大多数情况下,您无需担心 Java 中的显式内存管理 - 只要从列表中删除后没有其他对象引用它们,垃圾收集器就会(最终)删除它们。

如果enemies列表中的对象持有一些系统资源或其他需要明确处理的东西(比如文件句柄或其他东西),您需要在丢失引用之前清理它:

Enemy enemy = enemies.remove();
enemy.dispose(); // this is your method to clean up the internals - name it what you want
// continue your loop here

在与您的示例代码相关的注释中,您需要使用一个Iterator而不只是一个 for 循环来迭代索引,这样您就可以remove正确地进行操作,而不会遇到当前索引和列表大小的问题。您可能还需要考虑不同的List实现(例如LinkedList,如果它很大,从中间插入/删除ArrayList可能会变得昂贵。

对于您的其他问题:

有什么方法可以查看垃圾收集器是否正在删除对象?

你可以重写finalize你的类的方法——但是当你这样做时要小心。另请注意,无法保证您的对象何时会被垃圾收集 - 不同的 JVM 通常管理内存略有不同,并且通常仅在需要更多内存时才进行垃圾收集。

于 2013-03-27T05:58:28.143 回答