假设我想创建一个新实例 foo。
我会这样做:
SomeClass foo = new SomeClass();
现在假设对象已经到达终点(例如,就像游戏中的碰撞子弹)并且应该被处理和重新初始化。要重置对象,我可以这样做:
foo = new SomeClass();
或这个
foo.reset();
注意:该reset()
方法只会重置该实例中的所有变量。
哪个是更好的方法(当试图避免 GC 时)?第一个选项会创建一个新指针吗?
假设我想创建一个新实例 foo。
我会这样做:
SomeClass foo = new SomeClass();
现在假设对象已经到达终点(例如,就像游戏中的碰撞子弹)并且应该被处理和重新初始化。要重置对象,我可以这样做:
foo = new SomeClass();
或这个
foo.reset();
注意:该reset()
方法只会重置该实例中的所有变量。
哪个是更好的方法(当试图避免 GC 时)?第一个选项会创建一个新指针吗?
第一个选项创建一个新对象并将旧对象作为垃圾收集(除非有其他对它的实时引用)。
减少 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()
方法。
如果要避免 GC,则第二种选择更好。
实际上,即使选择第一个选项,JVM 也不会立即进行 GC。当堆已满(或者对于刚刚创建的对象来说不够用)时,它会进行 GC。第一个创建一个新实例,并且没有对旧对象的强引用。所以当JVM的堆满的时候,会做GC,老对象会被GCed。
此外,还有一些关于 GC 的内容,reference 就是你使用的那种引用。有四种引用,分别称为“强、软、弱、幻”。即使您使用第二个选项,对象“foo”也可能被 GCed,除非对对象“foo”的引用是强引用。请参阅 JDK 文档以获取有关四种引用类型的更多信息,例如 Reference Phantom SoftReference WeakReference