1

假设我想创建一个新实例 foo。

我会这样做:

SomeClass foo = new SomeClass();

现在假设对象已经到达终点(例如,就像游戏中的碰撞子弹)并且应该被处理和重新初始化。要重置对象,我可以这样做:

foo = new SomeClass();

或这个

foo.reset();

注意:该reset()方法只会重置该实例中的所有变量。

哪个是更好的方法(当试图避免 GC 时)?第一个选项会创建一个新指针吗?

4

2 回答 2

2

第一个选项创建一个新对象并将旧对象作为垃圾收集(除非有其他对它的实时引用)。

减少 GC 的一种策略是维护对象池。这将只是一个当前没有使用且可供重用的对象的集合。当您完成一个对象时,调用一个将其返回到池中的方法。当您需要一个新对象时,请在创建新对象之前调用一个检查池的方法;如果池不为空,它将从池中删除一个对象并重用它,而不是创建一个新对象。

public class SomeClass {
    private static final int MAX_POOL_SIZE = . . .;
    private static final ArrayList<SomeClass> pool = new ArrayList<SomeClass>();

    public static SomeClass getInstance() {
        int poolSize = pool.size();
        if (poolSize > 0) {
            return pool.remove(poolSize-1);
        }
        return new SomeClass();
    }

    public void recycle() {
        // reset any fields
        if (pool.size() < MAX_POOL_SIZE) {
            pool.add(this);
        }
    }
    . . .
}

当您需要新的SomeClass时,请致电SomeClass.getInstance()。完成一个实例后,调用它的recycle()方法。

于 2012-10-30T08:06:47.713 回答
0

如果要避免 GC,则第二种选择更好。

实际上,即使选择第一个选项,JVM 也不会立即进行 GC。当堆已满(或者对于刚刚创建的对象来说不够用)时,它会进行 GC。第一个创建一个新实例,并且没有对旧对象的强引用。所以当JVM的堆满的时候,会做GC,老对象会被GCed。

此外,还有一些关于 GC 的内容,reference 就是你使用的那种引用。有四种引用,分别称为“强、软、弱、幻”。即使您使用第二个选项,对象“foo”也可能被 GCed,除非对对象“foo”的引用是强引用。请参阅 JDK 文档以获取有关四种引用类型的更多信息,例如 Reference Phantom SoftReference WeakReference

于 2012-10-30T08:22:49.580 回答