勉強したことをメモ。
参考文献
以下記事が大変参考になった。
Javaパフォーマンスチューニング(3):Javaのヒープ・メモリ管理の仕組み (1/2) - @IT
第5回 チューニングのために理解しておきたいGCの4つのアルゴリズム:Javaはどのように動くのか~図解でわかるJVMの仕組み|gihyo.jp … 技術評論社
Java8のHotSpotVMからPermanent領域が消えた理由とその影響 | ギークを目指して
JVMのメモリ領域
大きく分けて「newしたオブジェクトを配置するヒープ領域(New領域+Old領域)」「その他、JVMの管理用変数を保持する領域(Permanent領域 or Metaspace領域+C Heap領域+ThreadStack領域)」からなる。
ヒープ領域
Javaでnewしたオブジェクトは、この領域にメモリ確保される。GCの処理の関係で、3つのセグメントを転々とする。
Eden領域
New領域と言われるものの1つ。
Javaでnewしたオブジェクトがまず最初に格納される。Scavenge GC という頻繁に行われるGCの対象領域。
Scavenge領域
New領域と言われるものの1つ。
「From領域+To領域」ともいわれる。
Eden領域にいながら1回のGCで破棄されなかったオブジェクトがコピーされてくる。真っ二つに分割されており、1回のGCコピーでは「Eden領域+片方の領域に残ってたもの」を「もう片方の領域に詰めながらコピー」。その次のコピーは反対に使う。その次はまた戻って・・・と「From」「To」の役割をフリップさせながらGCしながらコピーする。
この領域も、Scavenge GC という頻繁に行われるGCの対象となる。
JVMオプションで設定された回数だけ、オブジェクトはここに残る。
Old領域
Scavenge領域で、JVMオプションで設定された回数GCをしてもまだ残っているオブジェクトが移動される。
こちらは、Scavenge GC という頻繁に行われるGCの対象とならず、Full GCという大掃除の際にしかGCされない。
その他領域
超ざっくりした分類だが、これ以降はJVMの実装に深くかかわる。
Permanent領域 or Metaspace領域
クラスやメソッドのメタ情報を保持する領域。
ClassLoaderはclass fileを読み込んでここに書き込む。
Java 8 でPermanent領域は廃止され、Metaspace領域になった。
ちなみに、OutOfMemory対策に指定するオプション-XX:PermSizeは、Permanent領域のサイズ指定オプション。
(よくもまあ、知らずに使っていたものだ・・・)
ちなみに、Permanentは、正確にはヒープ領域に属するようだ。
C Heap領域
JavaVMの実装が使う、専用の領域。
OutOfMemoryが出ないクラッシュは、たいていここのOverrunだそうだ。(スレッドいっぱい作った時とか)
Thread Stack領域
いわゆるスタック領域。Javaのローカル変数などが書き込まれる。
少し驚いたのだが、Javaのスタックは、ブロック単位で積まれる。
つまり、forやifでブロックを組むことは、関数呼び出しに相当するとまではいかないが、それなりにコストを払った処理になる。