关于类实例的Java垃圾收集

时间:2013-11-23 02:36:57

标签: java garbage-collection

我对如何利用Java的垃圾收集来处理不再使用的对象的实例感到有些困惑。我有几个问题:

在我的游戏中,我生成Cannons而不将它们存储在如下变量中:

        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”的布尔字段。当“可见”等于假时,处理我的EnemyProjectile类并使其符合垃圾收集条件的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

使用Java的乐趣在于,在幕后为您管理内存,这样,与C或C ++不同,您不必担心解构或处理对象。当一个对象不再“可用”(由于超出范围并且无法从另一个活动对象访问而定义)时,垃圾收集器会悄悄地回收它所占用的空间。

在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中的数据结构时,您应该使用接口作为类型,而不是具体类。按照惯例,这样做可以使您的代码更加灵活。而不是......

ArrayList<Cannon> cannonList = Cannon.getCannons();

改为编写(对于实现List接口的任何类实例都有效):

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程序,使你的对象尽可能早地进行垃圾收集......然后不要担心会发生什么。