は、私は、コードJavaメモリーパズル
package memoryleak;
public class MemoryLeak {
public static int size;
static {
size = (int) (Runtime.getRuntime().maxMemory()*0.6);
}
public static void main(String[] args) throws InterruptedException {
{
byte[] data1 = new byte[size];
}
byte[] data2 = new byte[size];
}
}
このコードはOutOfMemoryErrorの発生を以下していると仮定します。このコードを1つの変数割り当て(最初の配列で使用されているスタックフレームを書き換え、配列をガーベジコレクションのために使用可能にする)で動作させることができます。このパズルはhereを説明しました。
{
byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
問題は次のコードがまだ機能しないのはなぜですか?
Object o = new Object();
synchronized (o) {
byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
そして、次の作品は:
Object o = new Object();
synchronized (o) {
byte[] data1 = new byte[size];
}
int i = 0;
synchronized (o) {
byte[] data2 = new byte[size];
}
yuck ...この動作は完全にガベージコレクタの実装に依存しませんか?これは、この振る舞いが確定的ではないようです(つまり、JLSでは指定されていません)。私が間違っている? – Tom
JLSでは、何もしないでGCを実装することができます(どのようにGCの契約を指定しますか?)。 –
記事にリンクされている記事を見ると、GCに依存するようには見えませんが、生成されたバイトコード(スタック上の配列リファレンスを長時間すぎないようにします)にあります。一方、この記事では、BEAやIBMのVMやSunの実験的な新しいガベージコレクタでは失敗しないとも述べています。混乱... – Thilo