请考虑以下情形: 您有一个代表某种数据提供者的单例类。 这个单例类分配了大量的内存,你希望它在没有人使用时释放它的已分配内存。 流速:
你如何建议在第3阶段实现单例(A类和B类“死”)将释放内存(我知道java使用垃圾收集,但仍然可以说我想要以下内存= null)。
PS 我不想强迫每个类在单例停止使用它时使用单例调用释放。我希望单身人士自己处理“释放”记忆。
答案 0 :(得分:7)
你能做的是
WeakReference
中。如果GC在其他地方仍然具有“强大”参考,那么这只会在GC之后保持活跃状态。如果WeakReference.get()
是null
,这意味着它已被收集,因为没有人强烈使用它,另一个弱引用不计算在内。如果再次需要它,您需要重新创建它和WeakReference
。
像这样,
public enum SingletonHolder{; // no instances
private static WeakReference<MyType> ref = null;
public static synchronized MyType getInstance() {
MyType type = ref == null ? null : ref.get();
if (type == null)
ref = new WeakReference<MyType>(type = new MyType());
return type;
}
}
BTW这假设需要此实例的实例保留对它的引用。这就是弱参考“知道”它仍然需要它的方式。
BTW2如果它是单线程的,你不需要同步,但它应该是无害的。
这意味着只有当新实例第一次需要它时才应该调用此方法,而不是每次都要调用此方法并使其更高性能不会产生太大影响,例如:双重检查只会让它变得复杂。
答案 1 :(得分:1)
使用Design pattern: "Singleton"
非常常见,常见的实施方法是使用static
reference
。
此实现的问题在于它多次离开floating garbage
未使用。
例如:
一个singleton
,其中包含DB connection pool
,只有应用程序在启动时才需要加载。
因此,更好的解决方案是对Singleton设计模式的扩展,称为WeakSingleton
。
当原始实例的所有其他引用都已过期时,此模式执行预期的操作,清除实例。
在java中实现此模式非常简单,可以基于WeakReferences
。
<强> E.g。代码:
public class WeakSingleton{
static private WeakReference singleton; // instance
public WeakSingleton getInstance(){
WeakSingleton m = (WeakSingleton)singleton.get();
if( m != null)
return m;
synchronized (WeakSingleton.class){
m = (WeakSingleton)singleton.get();
if( m != null)
return m;
m = new WeakSingleton(); // creates new instnace
singleton = new WeakReference(m);
}
return m;
}
}