量産メモ帳

忘れっぽいのでメモを残しています。

GCに関するメモ。

スポンサーリンク

開発で使用しているPCには1GBのメモリが搭載されているが、EclipseとAPサーバを立ち上げながらアプリケーション(画面)を動かしていると、時々、非常に重くなる。
またある画面から別画面を開いて閉じて開いて・・・を繰り返していると、OutOfMemoryエラーが発生してしまう。
そもそも1GBのPCで、IDEとAPサーバとアプリケーションを実行することに無理があるのかもしれないが、VMパラメータ次第で多少は問題を解決できるかもしれないと思い、時々、GCに関する資料を眺めている。
しかし一言でGCと言っても色々な呼び方があり、それぞれの意味と問題点をはっきりと把握していないことに気づいた。
なので、頭を整理するために、以下のURLを参考に各種GCの特徴を羅列。
現場から学ぶWebアプリ開発のトラブルハック(2):“Stop the World”を防ぐコンカレントGCとは? (1/2) - @IT
現場から学ぶWebアプリ開発のトラブルハック(2):“Stop the World”を防ぐコンカレントGCとは? (2/2) - @IT

  • メジャーGC:Old世代のGC。Mark-Sweep-Compact方式を採用。コストが高く時間がかかる。別名「Full GC」。
  • マイナーGC:New世代のGC。Copy方式を採用。高速。
  • 世代別GCJava VMのHeap領域をNew世代/Old世代に分け、オブジェクトの生存期間に応じてGCを効率化。生成された後、すぐに不要となる短命オブジェクトをNew世代領域で回収し、比較的長い期間必要となる長命オブジェクトをOld世代領域で長期的に管理。別名「スループットGC」。
  • パラレルGC:世代別GC複数のスレッドで実行するGC。ただし実行中は全てのアプリケーション・スレッドは停止される。
  • コンカレントGC:Old世代のGCをアプリケーションスレッドと並列に実行。しかし、GCアルゴリズム上、すべてのアプリケーションスレッドを停止する必要のある期間がどうしても存在するため、GCを4つのフェイズに分割して処理することで、その期間を最小化。ただし、GC実行中はGCスレッドが動作している分、負荷が高くなる。

ちなみに上記の@ITの記事だと、「コンカレントGCと世代別GCを組み合わせて使用」することがパフォーマンス改善に繋がると結論付けている。

そういやAPサーバを起動する時にVMパラメータを付加したら、最初、パラレルGCだったけど、途中でコンカレントGCに変更になって「Initial Mark」とか「Concurrent Mark」とか出てきたなー。
あれってこういうことだったのか!
なるほど、納得々々。
あとはヒープサイズとかその他のVMパラメータを設定し直して、動作を確認してみようかな。


後書き:
実際に動かしてみて、確かに停止する回数は減ったような気もするが、その代わり何となく重い気もした。
やはりプログラム次第なのかもしれない。