JVM の解毒: JVM と Java アーキテクチャ

JVM の解毒: JVM と Java アーキテクチャ

  [[322350]]

このような問題に遭遇したことはありませんか?

  • オンラインシステムが突然フリーズし、システムにアクセスできなくなったり、OOM が発生したりします。
  • オンライン JVM GC 問題を解決したいのですが、どこから始めればよいかわかりません
  • 新しいプロジェクトが立ち上げられたとき、さまざまな JVM パラメータ設定について混乱しました。私はデフォルトのものを使い、その後JJ
  • 面接を受けるたびに、JVM の原則と概念のいくつかを読み直さなければなりません。

このスローガンはよく書かれています。在宅勤務中に JVM について学ぶ機会を活用します。全体的な知識ポイントは次のとおりです。

Java 開発者は皆、JVM が Java 仮想マシンであることを知っています。学校で使っていた VM は仮想マシンとも呼ばれます。まずは比較してみましょう。

仮想マシンとJava仮想マシン

いわゆる仮想マシンは仮想コンピュータです。一連の仮想コンピュータ命令を実行するために使用されるソフトウェアです。一般的に、仮想マシンはシステム仮想マシンとプログラム仮想マシンに分けられます。

  • VirtualBox と VMware はシステム仮想マシンです。これらは物理コンピューターの完全なシミュレーションであり、完全なオペレーティング システムを実行できるソフトウェア プラットフォームを提供します。
  • プログラム仮想マシンの代表的なものは、単一のコンピュータ プログラムを実行するために特別に設計された Java 仮想マシンです。 Java 仮想マシンで実行される命令は、Java バイトコード命令と呼ばれます。

JVMとは

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

Java 仮想マシンはバイナリ バイトコードの実行環境であり、バイトコードを読み込み、対応するプラットフォームで実行するためのマシン命令に解釈/コンパイルする役割を担います。各 Java 命令には、オペランドの取得方法、オペランドの処理方法、処理結果の保存場所など、Java 仮想マシン仕様で詳細な定義があります。

特徴

  • 一度コンパイルすればどこでも実行可能(クロスプラットフォーム)
  • 自動メモリ管理
  • 自動ガベージコレクション機能

バイトコード

通常、Java バイトコードと呼ばれるものは、Java 言語で記述されたバイトコードを指します。正確に言うと、JVM プラットフォーム上で実行できるバイトコードの形式はすべて同じなので、総称して JVM バイトコードと呼びます。

異なるコンパイラで同じバイトコード ファイルをコンパイルでき、バイトコード ファイルは異なる JVM 上で実行することもできます。

Java 仮想マシンは必ずしも Java 言語に関連しているわけではありません。これは、特定のバイナリ ファイル形式 (クラス ファイル形式) にのみ関連付けられます。クラス ファイルには、Java 仮想マシン命令セット (バイトコードとも呼ばれます) とシンボル セット、およびその他の補助情報が含まれています。

Javaコード実行プロセス

JVMの場所

JVM はオペレーティング システム上で実行され、ハードウェアと直接やり取りすることはありません。

JDK (Java Development Kit) は、Java 言語用のソフトウェア開発キット (SDK) です。 JDK は、物理的には Java 言語、ツール、JRE、および JVM のコレクションとして存在します。

JVM 全体構造

JVM アーキテクチャ モデル

Java コンパイラによって入力される命令ストリームは基本的にスタックベースの命令セットアーキテクチャであり、もう 1 つの命令セットアーキテクチャはレジスタベースの命令セットアーキテクチャです。

2 つのアーキテクチャの違い:

  • スタックベースのアーキテクチャにより、設計と実装が容易になり、リソースが制限されたシステムに適しています。レジスタ割り当ての難しさを回避し、割り当てにゼロアドレス命令を使用します。命令ストリーム内の命令のほとんどはゼロアドレス命令であり、その実行プロセスは操作スタックに依存します。命令セットが小さくなり、コンパイラの実装が容易になります。ハードウェアのサポートは不要であるため、移植性が向上し、クロスプラットフォームの実装が容易になります。
  • レジスタベースアーキテクチャの特性の典型的な応用例は、従来の PC や Android の Davlik 仮想マシンなどの X86 バイナリ命令セットです。命令セットアーキテクチャはハードウェアに完全に依存しており、移植性が低い。優れたパフォーマンスとより効率的な実行。操作を完了するために必要な命令が少なくなります。ほとんどの場合、レジスタ アーキテクチャに基づく命令セットは、1 アドレス命令、2 アドレス命令、および 3 アドレス命令に基づくことが多いのに対し、スタック アーキテクチャに基づく命令セットは、0 アドレス命令に基づいています。

クロスプラットフォーム設計のため、Java 命令はすべてスタックに基づいて設計されています。プラットフォームによって CPU アーキテクチャが異なるため、レジスタベースで設計することはできません。利点は、クロスプラットフォーム、小さな命令セット、および簡単なコンパイラ実装です。欠点は、パフォーマンスが低下し、同じ機能を実現するためにより多くの命令が必要になることです。

スタックアーキテクチャに基づいてJVMコード実行プロセスを分析する

クラス ファイルがあるディレクトリに入り、javap -v xx.class を実行して逆解析を行う (または IDEA プラグイン Jclasslib を介して直接表示する) と、現在のクラスに対応するコード領域 (アセンブリ命令)、ローカル変数テーブル、例外テーブル、コード行オフセット マッピング テーブル、定数プールなどの情報が表示されます。

上図の 1+2 を例に挙げます。

  1. クラスファイル /Users/starfish/workspace/myCode/starfish-learning/starfish-learn/target/classes/priv/starfish/jvm/JVM1.class
  2. 最終更新日 2020-2-7;サイズ487 バイト
  3. MD5 チェックサム 1a9653128b55585b2745270d13b17aaf
  4. 編集  「JVM1.java」  
  5. パブリッククラス priv.starfish.jvm.JVM1
  6. ソースファイル: "JVM1.java"  
  7. マイナーバージョン: 0
  8. メジャーバージョン: 52
  9. フラグ: ACC_PUBLIC、ACC_SUPER
  10. 定数プール:
  11. #1 = メソッド参照 #3.#22 // java/lang/Object. 「<init>」 :()V
  12. #2 = クラス #23 // priv/starfish/jvm/JVM1
  13. #3 = クラス #24 // java/lang/Object
  14. #4 = Utf8 <init>
  15. #5 = Utf8()V
  16. #6 = Utf8 コード
  17. #7 = Utf8 行番号テーブル
  18. #8 = Utf8 ローカル変数テーブル
  19. #9 = Utf8 これ
  20. #10 = Utf8 Lpriv/starfish/jvm/JVM1;
  21. #11 = Utf8 メイン
  22. #12 = Utf8 ([Ljava/lang/String;)V
  23. #13 = Utf8 引数
  24. #14 = Utf8 [Ljava/lang/String;
  25. #15 = Utf8 i
  26. #16 = Utf8 I
  27. #17 = Utf8 j
  28. #18 = Utf8k
  29. #19 = Utf8 メソッドパラメータ
  30. #20 = Utf8 ソースファイル
  31. #21 = Utf8 JVM1.java
  32. #22 = NameAndType #4:#5 // "<init>" :()V
  33. #23 = Utf8 priv/ヒトデ/jvm/JVM1
  34. #24 = Utf8 java/lang/オブジェクト
  35. {
  36. パブリックpriv.starfish.jvm.JVM1();
  37. フラグ: ACC_PUBLIC
  38. コード:
  39. スタック=1、ローカル=1、args_size=1
  40. 0: ロード_0
  41. 1:invokespecial #1 // メソッド java/lang/Object。 「<init>」 :()V
  42. 4:戻る         
  43. 行番号テーブル:
  44. 3行目: 0
  45. ローカル変数テーブル:
  46. 開始長さスロット署名
  47. 0 5 0 この Lpriv/starfish/jvm/JVM1;
  48.  
  49. 公共 静的void main(java.lang.String[]);
  50. フラグ: ACC_PUBLIC、ACC_STATIC
  51. コード:
  52. スタック=2、ローカル=4、args_size=1
  53. 0: iconst_1 //コロンの前の数字はプログラムカウンタの番号を示し、定数1がスタックにプッシュされます
  54. 1: istore_1 //オペランドスタック1に保存します。1はオペランドスタックのインデックス位置を表します。
  55. 2: アイコンst_2
  56. 3: istore_2
  57. 4: iload_1 //ロード
  58. 5: ロード2
  59. 6: iadd // 定数をポップして合計する
  60. 7: istore_3 //インデックス3のオペランドスタックに格納
  61. 8:戻る         
  62. 行番号テーブル:
  63. 6行目: 0
  64. 7行目: 2
  65. 8行目: 4
  66. 9行目: 8
  67. ローカル変数テーブル:
  68. 開始長さスロット署名
  69. 0 9 0 引数 [Ljava/lang/String;
  70. 2 7 1 私
  71. 4 5 2 j 私
  72. 8 1 3 キロ 私
  73. メソッドパラメータ: 長さ = 0x5
  74. 01 00 0D 00 00
  75. }

JVM ライフサイクル

仮想マシンの起動

Java 仮想マシンの起動は、仮想マシンの特定の実装によって指定されるブートストラップ クラス ローダーを通じて初期クラスを作成することによって完了します。

仮想マシンの実行

  • 実行中のJava仮想マシンには、Javaプログラムを実行するという明確なタスクがあります。
  • プログラムの開始時に実行され、プログラムの終了時に停止します。
  • いわゆる Java プログラムを実行する場合、実際に実行されるのは Java 仮想マシンと呼ばれるプロセスです。
  • 同じマシン上で 3 つのプログラムを実行すると、3 つの Java 仮想マシンが実行されることになります。 Java 仮想マシンは常に main() メソッドから開始します。このメソッドは public で、void を返し、文字列配列のみを受け入れる必要があります。プログラムを実行するときは、main() メソッドを含むクラスの名前を Java 仮想マシンに指定する必要があります。

仮想マシンを終了する

いくつかの状況があります:

  • プログラムは正常に終了します。
  • プログラムの実行中に例外またはエラーが発生し、異常終了しました
  • Java仮想マシンのプロセスは、オペレーティング システム エラーのため終了しました。
  • スレッドがRuntimeクラスまたはSystemクラスのexitメソッド、またはRuntimeクラスのhaltメソッドを呼び出し、Javaセキュリティマネージャもこのexitまたはhalt操作を許可します。
  • さらに、JNI (Java Native Interface) 仕様では、JNI 呼び出し API を使用して Java 仮想マシンをロードまたはアンロードする場合の Java 仮想マシンの終了について説明しています。

Java および JVM の仕様

Java言語と仮想マシンの仕様

JVM 開発の歴史

JDK バージョンのアップグレードは、言語や機能の特徴に反映されるだけでなく、コンパイルおよび実行する Java 仮想マシンのアップグレードも含まれます。

  • 1990 年、サン コンピュータ コーポレーションでは、パトリック ノートン、マイク シェリダン、ジェームズ ゴスリングが率いるグリーン チームが、Oak という新しいプログラミング言語を開発しました。この言語は後に Java と命名されました。
  • 1995 年に、Sun は Java および HotJava 製品を正式にリリースし、Java が初めて一般公開されました。
  • 1996 年に JDK 1.0 がリリースされたとき、純粋に解釈された Java 仮想マシンの実装である Sun Classic VM が提供されました。
  • 1997 年に JDK 1.1 がリリースされたとき、仮想マシンは変更されず、引き続き Sun Classic VM がデフォルトの仮想マシンとして使用されていました。
  • 1998 年に JDK 1.2 がリリースされたとき、Solaris プラットフォーム上で実行される Exact VM 仮想マシンが提供されましたが、この時点では Sun Classic VM がまだデフォルトの Java 仮想マシンとして使用されていました。同時に、JSP/Servlet および EJB 仕様がリリースされ、Java は J2EE、J2SE、J2ME に分割されました。
  • 2000 年に JDK1.3 がリリースされ、デフォルトの Java 仮想マシンが Sun Classic VM から Sun HotSopt VM に変更され、Sun Classic VM がバックアップ仮想マシンとして使用されるようになりました。
  • 2002 年に JDK 1.4 がリリースされ、Sun Classic VM は商用仮想マシンの段階から撤退しました。これまで、Sun HotSpot VM がデフォルトの仮想マシンとして使用されていました。
  • 2003年にJavaプラットフォーム用のScalaが正式にリリースされ、同年にGroovyもJava陣営に加わった。
  • 2004年にJDK1.5がリリースされ、JDK5.0に改名されました。
  • 2006年にJDK6がリリースされました。同年、Java がオープンソース化され、OpenJDK が設立されました。当然のことながら、Hotspot仮想マシンはOpenJDKのデフォルトの仮想マシンにもなりました。
  • 2008年にオラクルはBEAを買収し、JRockit仮想マシンを手に入れた。
  • 2010年にオラクルはサンを買収し、Java商標とHotSpot仮想マシンを獲得した。
  • 2011年にJDK7がリリースされました。 JDK1.7u4 では、新しいガベージ コレクター G1 が正式に有効化されました。
  • 2014年にJDK8がリリースされ、PermGenがMetaSpaceに置き換えられました。
  • 2017年にJDK9がリリースされ、CMSに代わってG1がデフォルトのGCとして設定されました。

サンクラシックVM

  • 世界初の商用 Java 仮想マシン。これは 1996 年に Java 1.0 のリリースとともにリリースされ、JDK 1.4 で完全に廃止されました。
  • この仮想マシンはインタープリターのみを提供します。
  • JIT コンパイラを使用する場合は、プラグインを使用する必要があります。ただし、JIT コンパイラを使用すると、JIT が仮想マシンの実行システムを引き継ぎ、インタープリターは動作しなくなります。インタプリタとコンパイラは連携して動作できません。
  • ホットスポットにはこの仮想マシンが組み込まれています

正確なVM

  • その実行システムには、ホットスポット検出、2 レベルのジャストインタイム コンパイラ、コンパイラとパーサーの混合動作モードなど、最新の高性能仮想マシンの基本がすでに備わっています。
  • 正確なメモリ管理を使用します。仮想マシンはメモリ内の特定の場所にある特定のタイプのデータを認識できます。
  • これは商用アプリケーションでは短期間のみ存在し、より高度な HotSpot VM に置き換えられました。

サンホットスポットVM

  • これは Sun JDK および OpenJDK に含まれる仮想マシンであり、現在最も広く使用されている Java 仮想マシンです。
  • これは、Sun の以前の 2 つの商用仮想マシンの利点 (正確なメモリ管理など) を継承し、ホット コード検出テクノロジ (実行カウンタを通じて最もコンパイルに値するコードを見つけ、メソッド単位でコンパイルするように JIT コンパイラに通知する) などの独自の新しい技術的利点も多数使用します。
  • Oracle はそれぞれ BEA と Sun を買収し、JROKit のガベージ コレクターと MissionControl サービス、HotSpot の JIT コンパイラとハイブリッド ランタイム システムを使用するなど、JROKit VM と HotSpot VM を JDK8 に統合しました。

BEA JRockit VM

  • サーバー側アプリケーションに重点を置いており、内部にパーサーの実装は含まれていません。
  • 世界最速のJVMであると主張している

IBM J9 VM

  • 正式名称: IBM Technology for Java Virtual Machine、IT4J とも呼ばれ、内部コード: J9
  • 市場での位置付けは、HotSpot、サーバー、デスクトップ アプリケーション、組み込みなどの多目的 VM に近いです。
  • 現在最も影響力のある3つの商用仮想マシンの1つ

Azul VM、Liquid VM、Apache Harmony、TaobaoJVM、Graal VM など、多数の仮想マシンがあります。

<<:  ユーザーエクスペリエンスを定量化するにはどうすればよいでしょうか?パブリッククラウド製品のユーザーエクスペリエンス測定システムの構築に関する簡単な説明

>>:  マルチクラウドアーキテクチャが組織の焦点となる

推薦する

インターネットマーケティング - セルフマーケティング

マーケティングを行うときは、まず自分自身をマーケティングしなければならないと言う人がいます。この発言...

羅敏の狂気のライブ放送室、Qudian

7月17日、平凡な日曜日は、羅敏さんが自分のお金を使って「1セントで無料の漬物魚」福祉デーを作った日...

インターネット情報推奨アルゴリズムの簡単な分析

ルペン氏の時代から、彼が扇動と情報発信に長けていることは公然の秘密だった。しかし今日では、ビッグデー...

Jenkins パイプラインは Nexus リポジトリに成果物を公開します

このガイドでは、継続的インテグレーション サーバーとして Jenkins を使用し、ビルド リポジト...

ウェブマスターがお金を稼ぐための一般的な方法をいくつか紹介します

インターネットの誕生から、ナビゲーションサイト、検索エンジン、コミュニティ、ポータル、フォーラム、ニ...

母子向けサイトの動向は?

今日の社会において最も重要な家族関係は何でしょうか?夫婦関係?親子関係?義母と嫁の関係?親子関係こそ...

Baidu の Web ページ品質に関するホワイト ペーパーのサブテキストを解釈する

少し前に、Baidu のトラフィックのシェアが大幅に減少し、360 のトラフィックのシェアが大幅に増...

データを保存するのに最適な場所はどこですか? AIはユーザーにパブリッククラウドの使用を強制する

特にインテリジェント テクノロジーの需要が高い業界では、クラウド上で AI アプリケーションがますま...

チェスの観点から見たウェブサイト最適化の深い理解

チェス?SEO?この2つは関係ないように思えますが、今日Youyouranはウェブサイトの全体的なS...

AIを活用したインテリジェントオートメーションは、人間が「スーパーパワー」を獲得するのを助ける

朝起きると、ロボットがすでにさまざまな朝食を用意してくれています。外出前に、ロボットは天候に基づいて...

ウェブサイトのホームページがブロックされた後、1か月以内にスナップショットが復元され、ランキングが向上します。

簡単な説明: これは私が担当しているウェブサイトの SEO ランキングです。 1 か月も経たないうち...

cmivps: 米国の 3 ネットワーク Unicom AS4837 ライン VPS、20G 防御、月額 6 ドル、1G メモリ/1 コア/30g NVMe/2T トラフィック/1G 帯域幅

cmivpsは米国南部海岸のシアトルデータセンターにVPSを構え、中国聯通のAS4837回線に接続し...

週刊ニュースレビュー:Sina WeiboがWeiboに名前を変更、Alipayが4大銀行と競争して冷静に

1. Ctripの脆弱性は、インターネット業界全体のセキュリティ意識の欠如を露呈しているユーザーの支...

【WOT2018】Shen Jian: 58 Expressアーキテクチャの分離とマイクロサービスの実践

[51CTO.comより引用] 2018年5月18日〜19日、51CTO主催のグローバルソフトウェア...

グローバルクラウドコンピューティング導入を検討するための10のガイドライン

[[356853]]グローバル市場への認知度が高まるにつれ、ほとんどの組織はコストを削減し、市場投入...