2

以下のクラスは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; 
       */
    }
}

ハックの種類:

私は使用できます ConcurrentHashMap<String,A> -> get("OBJ-A"), replace("OBJ-A", newObjA)

これはReentrantReadWriteLockを使用しますが、まだ試していません。

では、実装する最良の方法は何でしょうrefreshA()か? GC は古い参照を削除する必要があることに注意してください。

4

2 に答える 2

1

まず第一に、ダブルチェック ロックは推奨されません。en.wikipedia.org/wiki/Double-checked_locking を参照してください。

置き換え可能なフィールドについては、AtomicReference を使用できます。

また、メモリ リークに関しては、実際のオブジェクトにプロキシを渡すことを検討してください。このようにして、バッキング インスタンスを交換し、誰も古いバッキング オブジェクトへの参照を保持しないようにすることができます。

于 2013-11-07T11:57:41.517 に答える