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 など、多数の仮想マシンがあります。

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

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

推薦する

vpeasy-18 USD/年/KVM/1GB メモリ/25GB SSD/1TB トラフィック/Windows/ラスベガス

vpeasy.com で夏休みプロモーションを実施中?実際のところ、vpeasy がなぜ生涯 35%...

GigsGigsCloud-香港VPS簡易評価、PCCW回線、100Mポート

gigsgigscloudは今年初めに設立されました。同社は香港に登録されており、中国人が運営してい...

ethernetservers-VPS は年間 7.5 ドルから、リソースは「言葉では言い表せない」ほど無料

ethernetservers の VPS がセール中であることがわかりました。通常価格の 50% ...

#BlackFriday# sharktech: 50% オフ、VPS、クラウド、Zhiqiang Gold サーバー、無料の 60G 防御、無制限のトラフィック、米国/オランダのデータセンター

アメリカの老舗高防御サーバーベンダーであるSharkte(2003年~)が、毎年恒例のブラックフライ...

ウェブマスターネットワークからの毎日のレポート:EUがグーグルへの課税を引き上げ、ヤフーは27億ドルの損害賠償を支払うよう命じられた

1. EUはグーグルなどの米国のインターネット大手への課税を強化する計画海外メディアの報道によると、...

7月12日の百度の調整結果に関する詳細な分析と提案

十数個のウェブサイトのデータを数え終えたところです。今朝目覚めると、手元にある十数個のウェブサイトが...

デジタルポイントカードは人気が高まっているが、グルーポンの共同購入モデルは課題に直面している

はじめに:海外メディアは本日、デジタルポイントカードプロジェクトを提供するスタートアップ企業が増えて...

ioncloud: 新年ロサンゼルス (CN2 GIA)「クラウド サーバー」60% オフ、「Alipay/PayPal」をサポート

Krypt Data Center 傘下のクラウド サーバー (VPS) ブランドである ioncl...

WeChatマーケティング:夕食後にユーザーが何をするかを考える

夜が静かになると、WeChat ユーザーは活発に動き始め、携帯電話を振り始めます。WeChat の使...

ブランドクライアントは SEM 配信の有効性をどのように評価しますか?

著者:Huang Hao はロッテルダム経営大学院を卒業し、金融投資を専攻しました。私は 2 年間 ...

地域間分散システムを構築するにはどうすればよいでしょうか?

マルチコンピュータ ルーム展開とは、異なる IDC (インターネット データ センター) コンピュー...

経済の不確実性と気候変動が将来のネットワークを再構築する

今日、動的な作業環境、変化するデバイス要件、経済の不確実性などの市場の力により、新しい働き方、ビジネ...

サンダーソフト:より多くの企業のコスト削減と効率化を支援するためにグローバル展開

今日、ますます多くの製造企業がインテリジェント製造を積極的に導入しています。その中でもAIによる目視...

TiDBの分散トランザクションモデルについてお話しましょう

[[379689]]この記事はWeChatの公開アカウント「プログラマーjinjunzhu」から転載...