下面的类在servlet的init()
方法上初始化。objA
仅用于读取,需要定期调用refreshA
方法以将其替换为新的A
实例。
问题 :
定期更新后,出现内存泄漏。 (我猜有一些悬空的引用存在A
的多个副本)
public Class A {
private static volatile A objA;
public static A getA(){
if(objA == null){
synchronized (A.class){
if(objA == null){
objA = new A(); //takes a long time to initialise and memory heavy
return objA;
}
}
}
return objA;
}
public static void refreshA (A newObjA){
// best way to do this ?
/*
objA = newObjA;
*/
}
}
有点hacky:
我可以用
ConcurrentHashMap<String,A> -> get("OBJ-A"), replace("OBJ-A", newObjA)
这将使用ReentrantReadWriteLock,但我还没有尝试过。
那么实现
refreshA()
的最佳方法是什么?请记住,GC应该删除旧的参考。 最佳答案
首先,不建议再次检查锁定
,请参阅en.wikipedia.org/wiki/Double-checked_locking。
至于可替换字段,可以使用AtomicReference。
关于内存泄漏,请考虑为实际对象提供代理。这样,您可以换出后备实例,并确保没有人保留对旧后备对象的引用。
关于java - 在运行时替换Java对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19835048/