Javaの基本知識としてJVMについて知っておこう
Javaは、SEの業界で知らない人はいないほどの有名で汎用性のある言語で、あらゆるプラットフォームで世界でも広く利用されている。
エンタープライズでも、ビジネスロジックをjavaで記述しているケースは多く、様々な現場で働くSEであればJavaについて最低限の知識は持っておくと良いだろう。
本稿ではJavaプログラムが動作する際の、JVMとそのメモリ領域について基本的な部分を紹介する。
Javaを動かす土台となるJVM
Javaメモリの話をする前に、JVMについて説明したいと思う。
“Java Virtual Machine”通称JVMとは、Javaのプログラムを動かすために必要な仮想マシンである。Javaは様々な環境で同じプログラムを動かすために、ハードウェアとプログラムの間に仮想マシンを用意することで、OSやハードの違いを吸収している。
図. JVMがOSの違いを吸収してくれている
JVMが存在することにより、私たちは稼動するプラットフォームを意識せずにコーディングを行うことができる。同一のJVM上であれば、どんなプラットフォーム上で稼動しているかに関わらず、同一の動作がすることが保障されているのである。
本稿では、このJVMがどういった構成になっているのか、メモリ構成について説明したい。
JVMのメモリ構成
Javaのプログラムが稼動するJVMのメモリは大別してヒープ領域と非ヒープ領域に分けられる。ヒープ領域には、New領域とOld領域が存在し、非ヒープ領域にはPermanent領域が含まれている。
このうち、New領域の中にはさらにEden領域とSurvivor領域(From,To)が存在している。文章で説明するとややこしく感じるが、図解すると以下のような形になっている。
図. JVMのメモリ構成
非ヒープ領域
[Permanent領域]
Permanent領域はクラスやメソッドなどの情報が格納される領域である。JSPを使用する場合などもPermanent領域が利用される。ロードするクラスが増えるとPermanent領域を逼迫するため、例えばClassを大量にロードする場合は領域のサイズに注意する必要がある。
図. Permanent領域
ヒープ領域
[New領域]
その名の通り、新しいオブジェクトを格納するためのメモリ領域。
New領域内はさらに「Eden」「From」「To」という3つの領域に分割されており、新しいオブジェクトが生成されたときに一番最初に格納されるの場所がEden領域である。
オブジェクトが生成されるたびに次々とEden領域に格納されていくので、そのうちEden領域はオブジェクトで一杯になる。
図. Eden領域にはオブジェクトが最初に生成されたときに格納されていく。
Eden領域が一杯になると、GC(ガベージコレクション)と呼ばれる機能が実行される。
GCとは、JVMが備えているお掃除機能であり、JVMのメモリが溢れないように不要なオブジェクトを破棄してメモリを開放してくれる働きをしている。
GCの働きにより、Eden領域のオブジェクトがクリーンアップされるが、使用中のオブジェクトはTo領域へと移動され、使用されていないオブジェクトは破棄される。結果としてEden領域に空きがうまれるので、新しいオブジェクトを作成することが可能となる。
図. GCによるEden領域のクリーンアップ-1
図. GCによるEden領域のクリーンアップ-2
その後、Eden領域がが一杯になると再度GCが稼動することになるが、このとき、前回To領域として扱われていた領域はFrom領域として扱われ、代わりに前回のFrom領域はTo領域として扱われる。
図. 再度GCが稼動する場合には前回のFromr領域がTo領域として扱われる
このGCではEden領域と同様に、From領域も対象にクリーンアップが行われ、未使用オブジェクトは削除され、使用中のオブジェクトはTo領域へと移動される。
図. Eden領域とFrom領域を対象にクリーンアップが行われる-1
図. Eden領域とFrom領域を対象にクリーンアップが行われる-2
以降もEden領域が一杯になるたびに、GCが稼動して同じ流れでクリーンアップが繰り返される。
SE Tips : GC(ガベージコレクション)
Javaには2種類のGCが存在する。上記で説明したGCはScavenge GCと呼ばれている軽量のGCで、実行時間が短い。ほかにFull GCと呼ばれるGCも存在しておりヒープ領域のOld領域があふれると発生する。Full GCはScavenge GCに比べて非常に実行時間が長い上に、実行中はシステムが停止する。
参考記事:
[Old領域]
その名の通り、古いオブジェクトを格納するための領域。New領域に生成されたオブジェクトが古くなると移動されてくる。新しく生成されたオブジェクトは上述した流れでFrom領域とTo領域を行き来することになるが、規定回数以上、From⇔Toの行き来を繰り返したオブジェクトはOld領域へと移動される。
図. 規定回数以上From/Toを行き来したオブジェクトはOld領域へ移動される
Old領域への移動は、使用頻度が高いオブジェクトが毎回GCの対象となりGCのパフォーマンスが落ちることを防ぐために行われる。
まとめ
- JVMはJavaを動かすための土台でハードやOSなど環境の違いを吸収してくれる
- JVMを構成するメモリはヒープ/非ヒープに分けられる。
- 非ヒープ領域にはクラス情報など静的な情報が格納される
- ヒープ領域には生成されたオブジェクトなど動的な情報が格納される
- ヒープ領域ではGCと呼ばれるメモリお掃除機能が定期的に実行されている
コメントを残す