Yoshi.dev

技術系の趣味、またはやった仕事やそこから学んだことを忘れないために

JVM基礎

Jvm

メモリ空間

  • JVM上にJavaヒープ、Cヒープ、スレッドスタックの3つのメモリ領域がある。基本的にヒープと呼ばれているのはJavaヒープのこと
  • ヒープが一杯になるとOOME(Out Of Memory Error)

ヒープの再利用

  • 参照のなくなったオブジェクトはGCが掃除してメモリを開放してくれる
  • GCは自動で行われるが、System.gc()メソッドで任意に実行させることもできる(ただやる必要はない)
  • GC後もメモリ使用量が増加してしまうことをメモリリークという。これはプログラムの実行に必要ないにもかかわらず参照が残ってしまい、メモリがうまく開放できないときに起こる。メモリリークが起きるとGCが頻繁に起こる。
  • メモリリークが発生してるとわかった場合は原因の特定に務める
  • ファイナランザfinalize()メソッドをoverrideしてGC回収前に行う処理を実装できる

システムトラブル

  • システムトラブルの原因として考えられること
    • リソース不足
    • コネクションやスレッドのプール数不足
    • GCへ与えるスレッド数が足りずCPUを使い切れていない
  • GCはヒープの空きメモリ量が少ないと頻繁に実行される。つまり生きてるオブジェクト(参照があるオブジェクト)が大量にあり、空きヒープがないとGCが頻発する
  • GCの種類によってはGCが発生中はアプリケーションが停止する。
  • 停止問題にはスループット(単位時間(1秒とか))あたりの処理量)とレスポンスタイムの2つの観点からの対処アプローチ方法がある
  • 1処理のレスポンスタイムは同タイミングでGCが発生する可能性があることを考えると、最悪GCの実行時間+処理の実行時間になってしまう
  • スループットを求める場合は、GCの回数を減らして一回あたりのGCの時間は長くなるが、トータルとして単位時間あたりのGC実行時間は減らせばスループットが上がるというアプローチ
  • レスポンスタイムを短縮したい場合はGCの回数は増えるが、一回一回のGCは短い時間で終わるため、アプリケーションのレスポンスタイム(処理の実行時間+GCの実行時間)は短く保てる

3つのGC

  • シリアルGC
    • 一つのスレッドによるGC
    • スレッド一つで行うためGCの時間が長くなる
    • その分アプリケーションスレッド(アプリケーションの処理)の停止時間も長くなる
  • パラレルGC
    • 複数のスレッドによるGC
    • シリアルGCより短い時間でGCが終わる(ただしGCスレッド間の同期処理等のオーバーヘッドがあるためシリアルGCでの停止時間/GCスレッド数とはならない
  • コンカレントGC
    • アプリケーションスレッドを停止せずにGCスレッドを動作させる方法
    • アプリケーションスレッドの停止時間が短縮できる。しかし完全に停止時間をなくすことはできない

GCの4つのアルゴリズム

  • マーク&スイープGC
    • マークフェーズとスイープフェーズという2つのフェーズを実行するアルゴリズム
    • マークフェーズでは生きているオブジェクトにマーク付をする
    • スイープフェーズではマークのついてないオブジェクトを削除する
    • ヒープの空きは増えるがメモリの断片化問題が発生する
  • コンパクション
    • メモリの断片化を直すアルゴリズム
    • ヒープ内にバラバラに配置されたオブジェクトを並べ替えて、メモリ空間の断片化をなくす
  • コピーGC
    • そもそもメモリの断片化が起きないようにするためのアルゴリズム
    • ヒープをFrom領域とTo領域に分ける
    • コピーGC実行のタイミングで生きているFrom領域のオブジェクトをTo領域に断片化が起きないようにコピーする
    • 終わったらFrom領域を空にする
    • 最後にFrom領域とTo領域をスイッチする
    • デメリットとしては、From領域とTo領域に分けるため、使える容量が半分になる
  • 世代別GC
    • ヒープ領域を若い世代と古い世代に分けてそれぞれ別でGC管理する
    • 世代を分けて管理することでGCの処理時間を短くできる(参照が残り続けるオブジェクトを何度GCしても無駄なので)
    • オブジェクトがGCされた回数=年齢と呼ぶ(生きたオブジェクト)
    • 若い世代で一定年齢上がったオブジェクトは古い世代となる
    • 古い世代のGC頻度は低く、若い世代のGC頻度は多い