⇧ 創作で使えなくなりますな...いや、反重力が存在する世界線とかの物語とかありと言えばありなのかしら?
ちなみに、ここで言っている「世界線」は、
⇧「パラレルワールド」の方の意味で使ってますので悪しからず。
Java仮想マシン(JVM:Java Virtual Machine)とは
何はともあれ、「Java仮想マシン(JVM:Java Virtual Machine)」とは何か、お浚い。
Java仮想マシン(ジャバかそうマシン、英語: Java virtual machine、Java VM、JVM)は、Javaバイトコードとして定義された命令セットを実行するスタック型の仮想マシン。APIやいくつかのツールとセットでJava実行環境(JRE)としてリリースされている。この環境を移植することで、さまざまな環境でJavaのプログラムを実行することができる。
⇧ ザックリ言うと、Javaで実装した処理を動かすために必要ですと。
英語版のWikipediaの説明だと、
A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. The JVM is detailed by a specification that formally describes what is required in a JVM implementation. Having a specification ensures interoperability of Java programs across different implementations so that program authors using the Java Development Kit (JDK) need not worry about idiosyncrasies of the underlying hardware platform.
⇧ 更に内部構造の図が掲載されている。
Oracleの公式のドキュメントだと、
⇧ 上図のように、
- JDK(Java Development Kit)
- JRE(Java Runtime Enviroment)
とかも出てくるけど、どちらにも、「Java仮想マシン(JVM:Java Virtual Machine )」は同梱されている。
Javaというプログラミング言語は、「Java仮想マシン(JVM:Java Virtual Machine )」ありきと言えそうですと。
Java仮想マシン(JVM:Java Virtual Machine)のメモリ構造
で、Javaのドキュメントの不思議なところは、OutOfMemoryErrorというメモリ起因によるエラーが存在するにも関わらず、メモリの構成についての図解が無いというね...
とりあえず、「ガベージ・コレクション(GC:Garbage Collection)」の話に絡めてでしかメモリ構造的な図解が見当たらないのですが、Javaにおける「ガベージ・コレクション(GC:Garbage Collection)」自体の説明が公式のドキュメントで見当たらないので、Wikipediaさんによる一般的な「ガベージ・コレクション(GC:Garbage Collection)」の説明によると、
In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector attempts to reclaim memory which was allocated by the program, but is no longer referenced; such memory is called garbage. Garbage collection was invented by American computer scientist John McCarthy around 1959 to simplify manual memory management in Lisp.
https://www.oracle.com/java/technologies/platform-glance.html
⇧ 自動的にメモリを管理してくれる仕組みですと。
で、「Java仮想マシン(JVM:Java Virtual Machine )」におけるメモリの構造が不明なため、「Java仮想マシン(JVM:Java Virtual Machine )」に関わるメモリの全量が分からないのですが、
There are three components of the JVM that are focused on when tuning performance. The heap is where your object data is stored. This area is then managed by the garbage collector selected at startup. Most tuning options relate to sizing the heap and choosing the most appropriate garbage collector for your situation. The JIT compiler also has a big impact on performance but rarely requires tuning with the newer versions of the JVM.
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
⇧ 「Java仮想マシン(JVM:Java Virtual Machine )」が利用するメモリの全量は不明なのですが、とりあえず、「Heap」が対象らしいということで、「Heap」のみについて考えれば良いらしい。
ただ、「Heap」の構造が、
⇧ 上記のようになっているらしいですと。
ただ、Java 6のドキュメントを見てみると、
⇧「Heap」の構造の図が出てくるのだけど、何か微妙に違っているように見えるんだが...
Java仮想マシン(JVM:Java Virtual Machine)のメモリ使用率を算出する計算式を知りたいんだが...
何と言うか、「Java仮想マシン(JVM:Java Virtual Machine )」が利用するメモリについて、登場人物の全量がハッキリしないのだが、jstatコマンド(jcmdの方を利用することを推奨してる)のドキュメントを確認してみる。
⇧「-gc option」に着目すると、『ガベージ・コレクションが行われたヒープの統計情報。』と説明があり、以下の項目の情報が取得できるらしいですと。
項目 | 内容 |
---|---|
S0C | Survivor領域0の現在の容量(KB)。 |
S1C | Survivor領域1の現在の容量(KB)。 |
S0U | Survivor領域0の使用率(KB)。 |
S1U | Survivor領域1の使用率(KB)。 |
EC | Eden領域の現在の容量(KB)。 |
EU | Eden領域の使用率(KB)。 |
OC | Old領域の現在の容量(KB)。 |
OU | Old領域の使用率(KB)。 |
MC | メタスペースの容量(KB)。 |
MU | メタスペースの使用率(KB)。 |
CCSC | 圧縮されたクラス領域の容量(KB)。 |
CCSU | 使用されている圧縮されたクラス領域(KB)。 |
YGC | Young世代のガベージ・コレクション・イベントの数。 |
YGCT | Young世代のガベージ・コレクション時間。 |
FGC | フルGCイベントの数。 |
FGCT | フル・ガベージ・コレクションの時間。 |
GCT | ガベージ・コレクションの総時間。 |
⇧ で、上記のどの項目を組み合わせたら、「Java仮想マシン(JVM:Java Virtual Machine )」のメモリの使用率が算出できるのかについて、全く説明が無いという...
何と言うか、JDK 21とかで新機能を追加とかする前に、このあたりの話についてドキュメントで説明して欲しいんだが...
ネットの情報によりますと、
ヒープの使用量の確認
ヒープは「Eden + Survivor(from+to) + Old」となるので、以下でヒープの利用/確保領域がわかる。
- ヒープの確保領域:[S0C] + [S1C] + [EC] + [OC]
- ヒープの利用領域:[S0U] + [S1U] + [EU] + [OU]
- MetaSpaceは非ヒープ領域に移動になったので含まれないはず。
⇧ とのこと。
なので、「Java仮想マシン(JVM:Java Virtual Machine )」のメモリの使用率は、
Java仮想マシン(JVM:Java Virtual Machine )のメモリの使用率 = (ヒープの利用領域:[S0U] + [S1U] + [EU] + [OU]) ÷ (ヒープの確保領域:[S0C] + [S1C] + [EC] + [OC])
⇧ ということになるんですかね?
Oracleの公式のドキュメントで計算式とか載せて欲しいですな...
ちなみに、
メモリー・リークの一般的な兆候の1つは、java.lang.OutOfMemoryError
例外です。通常、このエラーは、Javaヒープにオブジェクトを割り当てるための十分な空間がないときにスローされます。この場合、ガベージ・コレクタによって新しいオブジェクトを格納するための空間を確保することも、ヒープをこれ以上拡張することもできません。また、このエラーは、Javaクラスのロードをサポートするための十分なネイティブ・メモリーがないときにスローされる場合もあります。ガベージ・コレクションの実行に過剰な時間が消費され、メモリーがほとんど解放されていない場合、まれにjava.lang.OutOfMemoryError
がスローされることがあります。
OutOfMemoryError
例外を診断する最初の手順は、その例外の原因を突き止めることです。スローされた理由が、Javaヒープがいっぱいであるからなのか、それともネイティブ・ヒープがいっぱいであるからなのかを調べます。原因を見つけることができるように、例外テキストの最後に詳細なメッセージが含まれています(次の例外を参照)。
⇧ と仰っているにも関わらず、ヒープの使用率の計算式について言及が無いのは何故なのか...
流石、Oracleさん安定の不親切さ...
と言うか『OutOfMemoryError例外の理解』って言ってるのに理解させる気がないってところがイラっとさせてくれますな...
毎度モヤモヤ感が半端ない...
今回はこのへんで。