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

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

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

推薦する

ウェブサイトのポジショニングの意味を考え、ウェブサイトのマーケティングとプロモーションをうまく行いましょう

製品、コミュニケーション、イメージ、競争の4つの大きな変化を経て、以前の供給が需要を上回る現象と比較...

中国電子クラウド飛青プラットフォームは42日間で顧客向けに3つのシステムを開発

高水準プログラミング言語が発展し成熟するにつれて、従来のソフトウェアと SaaS ソフトウェアの市場...

簡単な説明: SEO の最高レベルとは何でしょうか?

SEO 業界で数年間働いた後でも、私はまだ自分を新人だと思っています。なぜなら、SEO 業界は非常に...

ftlcloud: 香港/米国、専用物理サーバー、200 元、2*e5-2630/32g メモリ/240gSSD+900G HDD、香港で 10M 帯域幅/米国で 30M 帯域幅、無制限トラフィック

ftlcloudは現在、米国と香港のデータセンターの独立サーバーでスーパーセールプロモーションを実施...

sharktech: 月額 149 ドル、ロサンゼルス 1Gbps 無制限トラフィック サーバー、60Gbps 高防御、e3-1270/16g/2T

SharkTech は現在、ロサンゼルスのデータセンターで特別な低価格サーバーを宣伝しています。この...

半額推奨: prometeus-15 ユーロ/KVM/4 コア/3g メモリ/80g SSD/4T トラフィック

「クラシック:プロメテウス-$3.8/KVM/512mメモリ/15gSSD/2Tトラフィック」は6月...

中国移動は数万のノードを管理するという課題に直面しており、オープンソースのOpenStackだけがそれを解決できる

最近、私が参加する IT カンファレンスでは、オープンソースがほぼ毎回言及されており、オープンソース...

自分自身と敵を知ることで、あらゆる戦いで勝利が保証されます。増え続けるクラウド コストをどうやって制御できるでしょうか?

現在、ますます多くの企業が IT インフラストラクチャを便利で柔軟なクラウド インフラストラクチャに...

リンクファクトリーは、ウェブサイトの構築を輸入および輸出し、他人や自分自身を傷つける

ますます多くのウェブサイトが開発の行き詰まりに陥っていますが、彼らは困惑しています。ウェブサイトのコ...

ベトナム VPS: tothost、年間 28 ドル、512M メモリ/1 コア/8g SSD/100M 帯域幅/無制限トラフィック

2009 年に設立されたベトナムのサーバー プロバイダーである tothost.vn は、主にベトナ...

外国貿易ウェブサイトのSEOを確保するには、仮想ホストとドメイン名が非常に重要です。

商業業務のチームは絶えず成長しており、対外貿易業務の業務も増加しており、中国の電子商取引は徐々に中国...

VirMach - $7.5/年/KVM/128MB RAM/20GB HDD/500GB 帯域幅/フェニックス/ダラス

VirMachは、様々なシリーズのVPSを提供し、多くの実績を持つ新興企業です。以前、E3 シリーズ...

垂直型電子商取引は「溝を越える」ことができるか?

現在、垂直型電子商取引が直面している困難は、オンラインショッピングの深さと幅が十分ではなく、ユーザー...

モバイル Web サイト構築プラットフォームを使用する際に注意すべき点は何ですか?

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますモバイルイ...

CtripとQunarが合併し、中国最大のオンライン旅行会社に

10月26日夜のニュース、Ctrip.comは今晩、Baiduとの株式交換取引に合意したと発表した。...