この記事はJVMについて深く理解するのに役立ちます

この記事はJVMについて深く理解するのに役立ちます

[[278753]]

1. JVMとは何か

JVM は Java Virtual Machine の略です。 JVM はコンピューティング デバイスの仕様です。実際のコンピュータ上でさまざまなコンピュータ機能をシミュレートして実装された架空のコンピュータです。

Java 言語の非常に重要な機能は、プラットフォームに依存しないことです。この機能を実現するための鍵は、Java 仮想マシンの使用です。一般的な高級言語を異なるプラットフォームで実行する場合、少なくとも異なるターゲット コードにコンパイルする必要があります。 Java 言語仮想マシンが導入された後は、異なるプラットフォームで実行するときに Java 言語を再コンパイルする必要がなくなりました。 Java 言語は、Java 仮想マシンを使用して特定のプラットフォームに関連する情報を保護します。これにより、Java 言語コンパイラは、Java 仮想マシン上で実行され、変更なしで複数のプラットフォーム上で実行できるターゲット コード (バイトコード) を生成するだけで済みます。 Java 仮想マシンがバイトコードを実行すると、特定のプラットフォーム上でバイトコードをマシン命令に解釈して実行します。これが、Java が「一度コンパイルすればどこでも実行できる」理由です。

2. JVMの概要

JVM は通常、クラス ローディング サブシステム (ClassLoader)、ランタイム データ領域、実行エンジン、ガベージ コレクションの 4 つの部分で構成されます。その中でも、最も気になるランタイムデータ領域、つまりJVMのメモリ部分は、メソッド領域(Method Area)、JAVAヒープ(Java Heap)、仮想マシンスタック(JVM Stack)、プログラムカウンタ、ネイティブメソッドスタック(Native Method Stack)で構成されています。

JVM アーキテクチャ

3.1 クラスローディングサブシステム

クラス ローダーは .class ファイルの読み込みを担当します。クラス ファイルにはファイルの先頭に特定のファイル マーカーがあり、ClassLoader はクラス ファイルのロードなどを担当します。実行できるかどうかは実行エンジンによって決定されます。

3.2 ランタイムデータ領域

スタックパイプが走行し、スタックパイプが格納されます。 JVM チューニングは主に Java ヒープとメソッド領域の最適化に重点を置いています。

3.2.1 方法領域

メソッド領域は、すべてのスレッドで共有されるメモリ領域です。これは、クラス情報、定数、静的変数、ランタイム定数プール、および JVM によってロードされたその他のデータを格納するために使用されます。

3.2.2 Javaヒープ

Java ヒープは、すべてのスレッドで共有されるメモリ領域です。 JVM の起動時に作成されます。この領域は JVM 内で最大であり、アプリケーション オブジェクトと配列を格納するために使用されます。 GCの主なリサイクルエリアでもあります。 JVM インスタンスにはヒープ メモリが 1 つだけあり、ヒープ メモリのサイズは調整できます。クラス ローダーはクラス ファイルを読み取った後、エグゼキュータの実行を容易にするために、クラス、メソッド、定数変数をヒープ メモリに配置する必要があります。ヒープ メモリは、新しい世代、古い世代、永続的な世代の 3 つの部分に分かれています。

例:

  • Jdk1.6 以前: 定数プールは永続世代に割り当てられます。
  • JDK 1.7: はい、ただし、永続世代は徐々に削除されています。
  • Jdk1.8 以降: 永続的な生成はありません。代わりにメタスペースを使用します (java.lang.OutOfMemoryError: PermGen スペース、このエラーは JDK1.8 では発生しません)。

3.2.3 Javaスタック(JVMスタック)

1) スタックとは何ですか?

Java スタックはスレッド専用であり、スレッドの作成時に作成されます。そのライフサイクルはスレッドのライフサイクルに従います。スレッドが終了すると、スタック メモリが解放されます。スタックにはガベージ コレクションの問題はありません。スレッドが終了すると、スタックは Over となり、そのライフ サイクルはスレッドと一致します。基本型の変数とオブジェクト参照変数は、関数のスタック メモリに割り当てられます。

2) スタックには何が格納されますか?

各メソッドが実行されると、スタック フレームが作成され、主に次の 3 種類のデータが格納されます。

ローカル変数テーブル: メソッド内の入力パラメータと出力パラメータおよび変数。

スタック操作: ポップとプッシュの操作を記録します。

スタック フレーム データ: クラス ファイル、メソッドなどを含む。

3) スタックの動作原理

スタック内のデータはスタック フレームの形式で存在します。スタック フレームは、メモリ ブロック、データ セット、メソッドおよびランタイム データに関するデータ セットです。各メソッドが呼び出されてから実行されるまでのプロセスは、スタック フレームがスタックにプッシュされてからスタックからポップされるまでのプロセスに対応します。

4) ネイティブメソッドスタック

ローカル メソッド スタックと JVM スタックは非常によく似た役割を果たし、スレッド プライベートでもあります。違いは、JVM スタックは JVM に Java メソッド (つまり、バイトコード) の実行を提供するのに対し、ローカル メソッド スタックは JVM が使用するネイティブ メソッドを提供するという点です。具体的なアプローチとしては、ネイティブ メソッドをローカル メソッド スタックに登録し、実行エンジンの実行時にネイティブ ライブラリをロードします。一部の仮想マシン (Sun Hotpot など) は、これら 2 つを直接 1 つに結合します。

5) プログラムカウンタレジスタ

プログラム カウンターは非常に小さなメモリ空間であり、ほとんど無視できます。各スレッドにはプログラム カウンターがあり、これはスレッド専用で、現在のスレッドによって実行されたバイトコードの行番号インジケータと見なすことができます。プログラム カウンターはメソッド領域内のメソッド バイトコード (次に実行される命令コード) を指し、実行エンジンは次の命令を読み取ります。

6) ランタイム定数プール

ランタイム定数プールはメソッド領域の一部であり、コンパイラによって生成されたさまざまなリテラルとシンボル参照を格納するために使用されます。このコンテンツは、クラスがロードされた後にメソッド領域の実行時定数プールに保存されます。クラス ファイル定数プールと比較すると、ランタイム定数プールはより動的です。新しい変数は、コンパイル時に決定される定数である必要はなく、実行時に定数プールに配置できます。最も重要なアプリケーションは、String クラスの intern() メソッドです。

3.3 実行エンジン

実行エンジンは、ロードされたクラスのメソッド、つまりメソッドに含まれる命令を実行します。実行エンジンは、命令単位で Java バイトコードを読み取ります。これは CPU のようなもので、マシン命令を 1 つずつ実行します。各バイトコード命令は、1 バイトのオペコードと追加のオペランドで構成されます。実行エンジンはオペコードを受け取り、オペランドに基づいてタスクを実行し、完了後に次のオペコードの実行を続行します。

ただし、Java バイトコードは、マシンが直接実行できる言語ではなく、人間が理解できる言語で記述されています。したがって、実行エンジンはバイトコードを JVM で直接実行できる言語に変換する必要があります。バイトコードは、次の 2 つの方法で適切な言語に変換できます。

  • インタプリタ: バイトコードを 1 つずつ読み取り、解釈して実行します。そのため、バイトコードを非常に高速に解釈できますが、実行は低速です。これはインタープリタ型言語の欠点です。
  • ジャストインタイム コンパイラ: インタープリタの欠点を補うために使用され、実行エンジンは最初に解釈された方法で実行し、適切な場合にジャストインタイム コンパイラがバイトコード全体をネイティブ コードにコンパイルします。そうすると、実行エンジンは実行メソッドを解釈する必要がなくなり、ネイティブ コードを通じて直接実行できるようになります。ネイティブ コードを実行する方が、行ごとに解釈するよりもはるかに高速です。ネイティブ コードはキャッシュに保存されるため、コンパイルされたコードは非常に高速に実行できます。

3.4 ガベージコレクション (GC)

3.4.1 ガベージコレクションとは

ゴミ収集はゴミのリサイクルです。簡単に言えば、ガベージリサイクルとは、メモリ内で使用されなくなったオブジェクトをリサイクルすることです。いわゆる使用中のオブジェクト(参照オブジェクト)は、プログラム内のポインタによって指し示されるオブジェクトです。一方、未使用のオブジェクト (参照されていないオブジェクト) はどのポインタによっても参照されないため、それらが占有するメモリも再利用できます。

ガベージ コレクションの基本的な手順は、次の 2 つのステップに分かれています。

  • メモリ内で使用されなくなったオブジェクトを見つける(GC判定戦略)
  • これらのオブジェクトによって占有されているメモリを解放する(GCコレクションアルゴリズム)

3.4.2 GC決定戦略

1) 参照カウントアルゴリズム

参照カウント アルゴリズムは、オブジェクトに参照カウンターを追加することです。参照されるたびに、カウンターの値は 1 ずつ増加します。参照が無効な場合、カウンター値は 1 減少します。カウンターが常に 0 になっているオブジェクトは、使用できなくなります。デメリット: オブジェクト間の循環参照の問題を解決するのは困難です。

2) ルート探索アルゴリズム

ルート検索アルゴリズムの基本的な考え方は、「GC ルート」と呼ばれる一連のオブジェクトを開始点として使用し、これらのノードから下方向に検索を開始することです。検索パスは参照チェーンと呼ばれます。オブジェクトを GC ルートに接続する参照チェーンがない場合 (つまり、オブジェクトが GC ルートから到達できない場合)、オブジェクトは使用できないことが証明されます。

Java 言語では、GC ルートとして使用できるオブジェクトは次のとおりです。

  • 仮想マシン スタック (スタック フレーム内のローカル変数テーブル) で参照されるオブジェクト。
  • メソッド領域内のクラスの静的属性によって参照されるオブジェクト。
  • メソッド領域で定数が適用されるオブジェクト。
  • ローカル メソッド スタック内の JNI (ネイティブ メソッド) によって参照されるオブジェクト。

注: ルート検索アルゴリズムで到達できないオブジェクトは、必ずしも死ぬ必要はありません。オブジェクトが本当に死んだと宣言するには、少なくとも 2 つのマーキング プロセスを経る必要があるためです。1 つ目は、GC ルートに接続されていない参照チェーンをマークすることです。 2 つ目は、GC による F-Queue 実行キュー内のオブジェクトの小規模なマーク付けです (オブジェクトは finalize() メソッドをオーバーライドする必要があり、呼び出されていません)。

3.4.3 GCコレクションアルゴリズム

1) マークスイープ

マーク アンド スイープ アルゴリズムは、ルート セット (GC ルート) からスキャンし、最初にリサイクルする必要があるすべてのオブジェクトをマークし (ルート検索アルゴリズム)、次にマークが完了した後にマークされたすべてのオブジェクトを均一に再利用します。

このアルゴリズムには 2 つの問題があります。

  • 効率の問題: マーキングとクリアリングのプロセスはどちらも効率的ではありません。
  • スペースの問題: マークスイープ後、大量の不連続なメモリフラグメントが生成されます。スペースの断片化が多すぎると、操作中に大きなオブジェクトを割り当てる必要があるときに連続メモリが不足し、事前に別のガベージ コレクションをトリガーする必要が生じる可能性があります。

2) コピーアルゴリズム

コピー アルゴリズムは、使用可能なメモリを容量に応じて 2 つの等しいブロックに分割し、一度に 1 つのブロックのみを使用します。このブロックのメモリが使い果たされると、生き残ったオブジェクトが他のブロックにコピーされ、使用済みのメモリ領域が一度にクリアされます。

3) マークコンパクト

マーク コンパクト アルゴリズムのマーキング プロセスはマーク スイープ アルゴリズムと同じですが、後続のステップではリサイクル可能なオブジェクトが直接クリーンアップされなくなりました。代わりに、残っているすべてのオブジェクトが一方の端に移動され、その後、終了境界の外側のメモリがクリーンアップされます。

4) ジェネレーションコレクション

世代別コレクション アルゴリズムは現在、ほとんどの JVM ガベージ コレクターで使用されています。その中心的な考え方は、オブジェクトのライフサイクルに応じてメモリをいくつかの異なる領域に分割することです。一般的に、ヒープ領域は Tenured 世代と Young 世代に分かれています。ヒープ領域の外側に、Permanent Generation という別の世代が存在します。旧世代の特徴は、ガベージ コレクションを実行するたびにリサイクルする必要があるオブジェクトの数が少ないことです。一方、新世代の特徴は、ガベージ コレクションを実行するたびにリサイクルする必要があるオブジェクトの数が多いことです。したがって、さまざまな世代の特性に応じて、最も適切な収集アルゴリズムを採用することができます。

若い世代の回復アルゴリズム(コピーアルゴリズムに基づく)

  • 新しく生成されたオブジェクトはすべて、まず若い世代に配置されます。若い世代の目標は、ライフサイクルの短いオブジェクトをできるだけ早く収集することです。
  • 新世代メモリは、1 つの Eden 領域と 2 つの Survivor (survivor0、survivor1) 領域に 8:1:1 の比率で分割されます。エデンエリアが 1 つ、サバイバーエリアが 2 つ (一般的に)。ほとんどのオブジェクトはエデンエリアで作成されます。リサイクル中、Eden 領域内の残存オブジェクトはまず survivor0 領域にコピーされ、その後 Eden 領域がクリアされます。 survivor0 領域もいっぱいになると、eden 領域と survivor0 領域内の生き残ったオブジェクトが別の survivor1 領域にコピーされ、その後 eden と survivor0 領域がクリアされます。このとき、survivor0 領域は空であり、次に survivor0 領域と survivor1 領域が入れ替わります。つまり、survivor1 領域は空のままになります。
  • survivor1 領域が eden と survivor0 の残存オブジェクトを格納するのに十分な大きさでない場合、残存オブジェクトは古い世代に直接格納されます。古い世代もいっぱいになった場合は、フル GC (メジャー GC) がトリガーされ、新しい世代と古い世代の両方がリサイクルされます。
  • 新しい世代で発生する GC はマイナー GC とも呼ばれます。 MinorGC はより頻繁に発生します (Eden 領域がいっぱいになったときに必ずしもトリガーされるわけではありません)。

古い世代(Tenured Generation)のリサイクルアルゴリズム(主にマークスイープとマークコンパクト)

  • 若い世代で N 回のガベージ コレクションを生き残ったオブジェクトは、古い世代に配置されます。したがって、古い世代に保存されているオブジェクトは、ライフサイクルが長いオブジェクトであると考えられます。
  • メモリは新世代のものよりはるかに大きくなっています(比率はおよそ1:2)。古い世代のメモリがいっぱいになると、メジャー GC、つまりフル GC がトリガーされます。 Full GC の頻度は比較的低く、古い世代のオブジェクトの生存時間は比較的長く、生存率マークは高くなります。

永久世代リサイクルアルゴリズム

Java クラス、メソッドなどの静的ファイルを保存するために使用されます。永続的な生成はガベージ コレクションに大きな影響を与えませんが、Hibernate などの一部のアプリケーションでは、一部のクラスを動的に生成したり呼び出したりすることがあります。この場合、操作中に新しく追加されたクラスを保存するために、より大きな永続的な生成領域を設定する必要があります。永続的な世代はメソッド領域とも呼ばれます。メソッド領域でリサイクルされる主な内容は、放棄された定数と役に立たないクラスです。放棄された定数もルート検索アルゴリズムによって決定できますが、役に立たないクラスの場合は、次の 3 つの条件を同時に満たす必要があります。

  • このクラスのインスタンスはすべてリサイクルされています。つまり、Java ヒープ内にこのクラスのインスタンスは存在しません。
  • クラスをロードした ClassLoader がリサイクルされました。
  • このクラスに対応する java.lang.Class オブジェクトはどこからも参照されておらず、このクラスのメソッドはどこからもリフレクションを通じてアクセスできません。

3.4.4 ガベージコレクター

1) シリアルコレクター(コピーアルゴリズム)

新世代のシングルスレッドコレクターは、マーキングとクリーニングがシングルスレッドであるため、シンプルさと効率性の利点があります。これはクライアント レベルでのデフォルトの GC モードであり、-XX:+UseSerialGC を通じて強制的に指定できます。

2) シリアルオールドコレクター(マークスイープアルゴリズム)

旧世代のシングルスレッド コレクター、旧世代バージョンのシリアル コレクター。

3) ParNewコレクター(ストップコピーアルゴリズム)

新世代のマルチスレッド コレクターは、実際にはシリアル コレクターのマルチスレッド バージョンであり、マルチコア CPU 環境ではシリアルよりも優れたパフォーマンスを発揮します。

4) 並列スカベンジコレクター(ストップコピーアルゴリズム)

高スループットと CPU の効率的な使用を追求した新世代の並列マルチスレッド コレクター。スループットは通常 99% です。スループット = ユーザー スレッド時間 / (ユーザー スレッド時間 + GC スレッド時間)。高いインタラクティブ応答を必要としないバックグラウンド アプリケーションなどのシナリオに適しています。これは、サーバー レベルで使用されるデフォルトの GC メソッドです。強制するには -XX:+UseParallelGC を使用し、スレッドの数を指定するには -XX:ParallelGCThreads=4 を使用します。

5) 並列オールドコレクター(ストップコピーアルゴリズム)

旧世代の並列マルチスレッド コレクター、旧世代バージョンの Parallel Scavenge コレクター、並列コレクター、スループット優先。

6) CMS (並行マークスイープ) コレクター (マークスイープアルゴリズム)

CMS コレクターは、最短のリカバリ一時停止時間を取得することを目的としたコレクターです。 CMS コレクターは、「Mark-Sweep」アルゴリズムに基づいて実装されています。全体のプロセスは次の 4 つのステップに分かれています。

  • 初期マーキング: GC ルートが直接関連付けることができるオブジェクトを非常に高速にマーキングします。
  • 同時マーキング: GC ルート トレースを実行するプロセス。
  • 再マーキング: 同時マーキング中にユーザー プログラムが継続して動作したためにマーキングが変更されたオブジェクトのマーキング レコードを修正します。このステージの一時停止時間は通常、初期マーキング ステージよりもわずかに長くなりますが、同時マーキング時間よりも短くなります。
  • 同時クリア: プロセス全体で最も時間のかかる同時マーキングおよび同時クリア プロセスのコレクター スレッドは、ユーザー スレッドで動作できます。したがって、通常、CMS コレクターのメモリ回復プロセスは、ユーザー スレッドと同時に実行されます。
  • 利点: 同時収集、低停止
  • デメリット: CPU リソースに非常に敏感で、浮動ガベージを処理できず、大量のスペースの断片化が発生します。

7) G1 (ガベージファースト) コレクター (マークコンパクトアルゴリズム)

G1 は、サーバー側アプリケーション用のガベージ コレクターです。これは、「マークコンパクト」アルゴリズムに基づいて実装されています。他の GC コレクターと比較して、G1 には次の特徴があります。

  • 並列性と同時実行性
  • 世代別コレクション
  • 宇宙統合
  • 予測可能性の一時停止

G1操作手順:

  • 初期マーキング(ワールドイベントを停止し、CPU はガベージ処理のためだけに一時停止します)
  • 同時マーキング(ユーザースレッドとの同時実行)
  • 最終マーク (ワールド イベントを停止し、CPU はガベージの処理を一時停止します)
  • フィルターコレクション(ワールドイベントを停止し、ユーザーが予想するGC一時停止時間に応じてリサイクルする)

3.4.5 ガベージコレクション構造図

<<:  CIO: マルチクラウド戦略を採用することの長所と短所、そしてアドバイス

>>:  マルチクラウド戦略の長所と短所、および推奨事項

推薦する

Zookeeper を廃止した後、Kafka はトピックとコンシューマー グループをどのように保存しますか?

筆者の会社で現在使用している Kafka のバージョンは 2.2.1 であるため、Kafka カーネ...

海外調達:綱渡りビジネスの巨大産業チェーンには法的リスクが潜む

わが国では、海外購買は非常に成熟した産業チェーンを形成しています。国内の大手電子商取引プラットフォー...

IBM Feng Liang: ハイブリッドクラウド時代のネイティブセキュリティ

今年の突然の疫病の発生は、企業にとって前例のない「試練」をもたらした。この過程で、私たちはさまざまな...

Hostgator - 3.52% オフの割引コード + 40% オフの割引コード/無制限のウェブサイト構築/cpanel 仮想ホスト

Hostgator の公式仮想ホスティングはますます高価になってきているのでしょうか?実際、blue...

アンカーテキストを使用してウェブサイトを最適化する方法

ウェブサイトの最適化は、従来のマーケティングとは異なり、細心の注意を要する作業です。ウェブサイトの最...

テンセントクラウドデータベースが戦略的なアップグレードを開始し、5つの新しいデータベース製品をリリース

テンセントクラウドデータベースは8月28日、北京で正式に戦略アップグレードを開始し、今後はクラウドネ...

WeChatはショートマイクロブログマーケティングに取って代わることができるか?

モバイルインターネットの発展に伴い、人々はますますインターネットに依存するようになっています。WeC...

大きな進歩、世界的なクラウドコンピューティングベンダーがブロックチェーンの開発に協力

中国工業情報化部が最近発表した「2018年中国ブロックチェーン産業白書」によると、2018年3月末現...

内部ウェブサイト最適化のための 404 エラー ページを設計する際に注意すべき 3 つのポイント

ウェブサイトを運営している友人は、ウェブサイトのアップグレード、システムの変更、仮想ホストの変更など...

ウェブサイトタイトルの価値ポジショニング

ウェブサイトのタイトルはウェブサイトの核となるキーワードです。ユーザーがキーワードを検索するときに、...

Ceph 分散ストレージ - 一般的な OSD のトラブルシューティング

[[264128]] 1. 一般的な OSD のトラブルシューティングOSD のトラブルシューティン...

ブログの人気を高める5つの方法

ブログ記事を公開しても誰も読まなければ、ブログが存在する意味がありません。個人ブログやビジネスブログ...

投稿を探すことは金を探すことよりも優れており、ウェブサイトがすぐに商業化されるのに役立ちます

フォーラムでは、ナビゲーション、トピック、推奨事項、ランキングなどの一連の手段の最終的な目標は、ユー...

#米国サーバー# フェニックスの最高級コンピュータールーム。サーバー割引も超格安。強くお勧めします

最近、米国アリゾナ州で最高に素晴らしいコンピュータ ルームを見つけました: phoenixnap.c...