我对如何利用 Java 的垃圾收集来处理不再使用的对象实例感到有点困惑。我有几个问题:
在我的游戏中,我生成大炮,但没有将它们存储在变量中,如下所示:
new Cannon("down", tileX, tileY, 65);
该对象是否始终符合垃圾回收条件?如果是,那么什么时候才会真正处理掉?
==
对于我的 Cannon 类,我在创建时将所有实例添加到静态数组列表中。这是我第一次尝试使用垃圾收集:
ArrayList<Cannon> cannonList = Cannon.getCannons();
for (int i = 0; i < cannonList.size(); i++) {
Cannon c = (Cannon) cannonList.get(i);
c = null;
}
for (int i = 0; i < cannonList.size(); i++) {
cannonList.remove(i);
}
System.gc();
当我设置“c = null;”时,它是否使原始 Cannon 为“null”,从而使其符合垃圾回收条件,或者是否为该对象创建一个新的引用 c,然后将其设置为 null,让它对我毫无作用?
==
我的 Cannon 类不断创建 EnemyProjectile 类的实例。 EnemyProjectiles 类包含一个名为“visible”的 boolean 字段。当“visible”等于 false 时,处理我的 EnemyProjectile 类并使其符合垃圾回收条件的正确方法是什么?
最佳答案
使用 Java 的乐趣在于,内存是在幕后为您管理的,因此与 C 或 C++ 不同,您不必担心对象的解构或处置。当一个对象不再“可用”(定义为超出范围并且无法从另一个 Activity 对象访问)时,垃圾收集器会悄悄地回收它所占用的空间。
在 Java 中,您无法控制对象何时被垃圾回收,也不应该尝试。
依赖于未使用对象的确定性垃圾收集的代码总是很脆弱并且难以在 Java 中维护。部分原因是不同的 JVM 实现会在不同的时间进行垃圾收集。 System.gc();
充其量只是向 JVM 提出垃圾回收的建议,但不能保证垃圾回收何时(或是否)发生。
你能做的最好的事情就是设计你的程序,使引用变量的生命周期绝对尽可能短。每当长生命周期对象保留对短生命周期对象的引用(监听器就是一个例子)时,或者当您创建自己“管理内存”的数据结构(例如您自己的队列或堆栈)时,您的代码就面临内存泄漏的风险实现)。
ArrayList<Cannon> cannonList = Cannon.getCannons();
for (int i = 0; i < cannonList.size(); i++) {
Cannon c = (Cannon) cannonList.get(i);
c = null;
}
for (int i = 0; i < cannonList.size(); i++) {
cannonList.remove(i);
}
System.gc();
在此片段中,有几个问题:
当您使用 Java Collections API 中的数据结构时,您应该使用接口(interface)作为类型,而不是具体类。这是按照惯例,但这样做将使您的代码更加灵活。而不是...
ArrayList<Cannon> cannonList = Cannon.getCannons();
改为这样写(对任何实现 List 接口(interface)的类实例都有效):
List<Cannon> cannonList = Cannon.getCannons();
如果可能,您应该使用 Java SE 5 中引入的增强的 for-each 循环。它不太容易出错。您的 for 循环应如下所示:
for (Cannon c : cannonList) {
c = null; // this for loop actually accomplishes no useful work since
// the reference is null'd as soon as it gets a reference to
// a Cannon object. The reference in your ArrayList is unaffected
// by this assignment
}
cannonList.clear(); // more concise than removing each element from the list.
TL;DR:垃圾收集发生时就会发生。它是不确定的。永远无法保证它何时或是否会发生。设计您的 Java 程序,使您的对象能够尽早进行垃圾回收……然后就完全不用担心会发生什么。
关于关于类实例的 Java 垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20157835/