下面的类在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/

10-12 02:53