2006年10月15日

弱参照キャッシュの罠

 Javaの弱参照をキャッシュに使いましょう、という話がよくある。しかしこの手を考えなしに使うと、罠にはまる。私がはまった。
 キャッシュ対象を生成する操作で、大量のメモリを確保・解放したら、なにが起こるか? あるときはなにも起こらない。あるときはガベージコレクションが起こる。起動後しばらくは前者であることが多い。起動からしばらくすると、後者がぼちぼちと起こるようになる。
 ガベージコレクションは弱参照を消してしまう。
 ということは、だ――キャッシュ対象Aを生成するときにB, C, D...が消されてしまい、その消されたBを生成するときにA, C, D...が消されてしまい…… という現象が起こる。しかもこの現象は、起動直後には起こらず、しばらく経ってから起こるようになる。
 いったんこの現象が起こると、まるでスイッチが入ったように止まらなくなる。特に、複数スレッドでキャッシュ対象を生成している場合には顕著だ。キャッシュが効いているあいだには、めったにキャッシュ対象生成は起こらない。しかし、いったんガベージコレクションが起きたが最後、複数スレッドで同時にキャッシュ対象を生成しようとするため、いっそうガベージコレクションを起こしやすくなってしまう。
 対策は、弱参照ではなくLRUMapを使うこと。

Posted by hajime at 2006年10月15日 22:45
Comments