1+2のプロセスを理解すれば、Java仮想マシンを理解できる

1+2のプロセスを理解すれば、Java仮想マシンを理解できる

[[322423]]

面接中に JVM に関連する質問をされると、多くの面接者は機械的に暗記しており、詳細を尋ねられると答えるのをやめてしまうことに気付くでしょう。彼らは暗記するタイプで、おそらく意味を理解せずに本の中の大まかな概念や絵を覚えているだけでしょう。

実際、このコンテンツを読む際には、簡単なプログラム分析と比較するとより理解しやすくなります。始めましょう。

市販されている一般的な JVM の本では、JVM のアーキテクチャは一般に次の部分に分かれています。

  1. クラスローダー
  2. プログラムカウンタレジスタ(PCレジスタ)
  3. Java 仮想マシン スタック
  4. ヒープ
  5. 方法領域
  6. 実行時定数プール
  7. ネイティブメソッドスタック
  8. スタックフレーム
  9. 実行エンジン

項目 2 ~ 7 は、ランタイム データ領域とも呼ばれます。結局のところ、これらは JVM が実行されているときにのみ作成されます。この分類は基本的に Java 仮想マシン仕様を参照します。

無意味に概念を暗記すると、食べた後に忘れてしまう可能性があります。次に、1+2 プログラムを使用して理解してみましょう。

Java プログラミングを初めて学ぶときに、ほとんど全員が書いたことがある Hello World に似たプログラムを見てみましょう。

  1. パブリッククラスHelloWorld {
  2. 公共 静的void main(String[] args) {
  3. 整数a = 1;
  4. b = 2 ;
  5. c = a + b ;
  6. }
  7. }

javac でコンパイルした後、javap -verbose HelloWorld を使用して観察すると、次のような出力が表示されます。

  1. パブリッククラス HelloWorld
  2. マイナーバージョン: 0
  3. メジャーバージョン: 55
  4. フラグ: (0x0021) ACC_PUBLIC、ACC_SUPER
  5. this_class: #2 // HelloWorld
  6. スーパークラス: #3 // java/lang/Object
  7. インターフェース: 0、フィールド: 0、メソッド: 2、属性: 1
  8. 定数プール:
  9. #1 = メソッド参照 #3.#12 // java/lang/Object. 「<init>」 :()V
  10. #2 = クラス #13 // HelloWorld
  11. #3 = クラス #14 // java/lang/Object
  12. #4 = Utf8 <init>
  13. #5 = Utf8()V
  14. #6 = Utf8 コード
  15. #7 = Utf8 行番号テーブル
  16. #8 = Utf8 メイン
  17. #9 = Utf8 ([Ljava/lang/String;)V
  18. #10 = Utf8 ソースファイル
  19. #11 = Utf8 HelloWorld.java
  20. #12 = NameAndType #4:#5 // "<init>" :()V
  21. #13 = Utf8 HelloWorld
  22. #14 = Utf8 java/lang/オブジェクト
  23. {
  24. HelloWorld() をパブリックにします
  25. 記述子: ()V
  26. フラグ: (0x0001) ACC_PUBLIC
  27. コード:
  28. スタック=1、ローカル=1、args_size=1
  29. 0: ロード_0
  30. 1:invokespecial #1 // メソッド java/lang/Object。 「<init>」 :()V
  31. 4:戻る 
  32. 行番号テーブル:
  33. 1行目: 0
  34.  
  35. 公共 静的void main(java.lang.String[]);
  36. 記述子: ([Ljava/lang/String;)V
  37. フラグ: (0x0009) ACC_PUBLIC、ACC_STATIC
  38. コード:
  39. スタック=2、ローカル=4、args_size=1
  40. 0: アイコン 1
  41. 1: istore_1
  42. 2: アイコンst_2
  43. 3: istore_2
  44. 4: ロード1
  45. 5: ロード2
  46. 6: 追加
  47. 7: istore_3
  48. 8:戻る 
  49. 行番号テーブル:
  50. 3行目: 0
  51. 4行目: 2
  52. 5行目: 4
  53. 6行目: 8
  54. }

わかった。上記は Java バイトコードであることは誰もが知っています。上記の出力から、自分自身を仮想マシンとして想像して実行すると、Java 仮想マシンのさまざまな部分を理解できるようになります。

まず、コンテンツのこの部分を実行するには、まずメモリに読み込む必要があります。これらのコンテンツを読み取る負荷は、仮想マシンのクラス ローダーです。

ロードされるのは実際にはバイナリ ストリームであり、使いやすいように対応する形式に整理する必要があります。たとえば、このクラスの名前は何なのか、誰から継承されているのか、どのようなメソッドがあるのか​​、メソッド名は何なのか、内容は何なのか、などです。これらのものはどこかに保管する必要があります。どこに置けばいいですか?メソッド領域はこのためのものです。

いわゆるランタイム定数プールもメソッド領域内の領域です。調べてみると、定数プールは実行時に実行時定数プールに解析されます。他のクラスへの参照などが含まれる場合、ここでのシンボリック参照は、ロード後のリンク時に直接参照に変換されます。

他の部分はどうですか?一般的に、メソッド内の特定のコンテンツを実行するために使用されるのは、Java 仮想マシン スタック (よくスタックと呼ばれるもの) です。この部分は実はこのように理解することができます。 Java 仮想マシンは、実際の物理マシンと同様に、プログラムによって提供される命令を実行しますが、仮想マシンは限られた命令セットを提供するソフトウェアです。物理マシンは基本的にレジスタに基づいて実行されますが、Java 仮想マシンの命令の実行はスタックに基づいています。

スタックなので、スタックには何を入れればよいでしょうか?そうです、それはスタック フレームであり、IDE デバッグを使用するときに表示されるレイヤーごとのコンテンツです。

各メソッドが呼び出されるとフレームが表示されます。各フレームも構造体であり、メソッドの実行に使用されるすべてのものがその中に含まれています。たとえば、デバッグ時には通常、各変数とその値が表示されます。これらの変数はローカル変数と呼ばれます。上記の出力には、stack=2、locals=4、args_size=1 があります。 locals はローカル変数、args_size はメソッド パラメーターの長さ、その他はオペランド (スタック)、値はスタックの最大深度であることがわかります。

各クラスのどのメソッドにもフレームがあり、フレームには独自のローカル変数テーブル、独自のオペランド スタック、およびランタイム定数プールへの参照があります。もちろん、デバッグ情報などの拡張情報も含まれる場合があります。

具体的には、上記の単純な 1+2 演算は、次の JVM 命令に対応します。

  1. 0: アイコン 1
  2. 1: istore_1
  3. 2: アイコンst_2
  4. 3: istore_2
  5. 4: ロード1
  6. 5: ロード2
  7. 6: 追加
  8. 7: istore_3
  9. 8:戻る 

現在実行されている命令を知るための識別子が必要であり、このタスクはプログラム カウンターによって実行されます。その男は、次に実行される命令を指さし続けました。基本スタックの実装。上記の手順では、大まかに言って、定数 1 を最初の変数に割り当て、定数 2 を 2 番目の変数に割り当てます。その後、変数 1 がスタックにプッシュされ、変数 2 がスタックにプッシュされます。 iadd 操作が実行されると、2 つのデータがスタックからポップされ、合計が完了し、変数 3 に割り当てられ、スタックにプッシュされてから返されます。これについては、次回 JVM 命令について説明するときに詳しく説明します。もちろん、これらの命令の実行は実行エンジンから切り離すことはできません。

ネイティブ メソッドを実行する必要がないため、JNI などのローカル メソッド実装用に用意されているローカル メソッド スタックは通常使用しません。

1+2 のプロセスを観察してみると、Java 仮想マシンの基本的な構造が理解できましたか? :-) それでも思い出せない場合は、このように考えてみてください。 Java の世界では、ヒープとスタックがよく言及されます。スタックには何が保存されますか?デバッグ時に見たフレームのレイヤーについて考え、次に今日の 1+2 の実行について考えれば、すべてがわかるはずです。

この記事はWeChatの公開アカウント「Tomcat Things」から転載したものです。以下のQRコードからフォローできます。この記事を転載する場合は、Tomcat Things の公開アカウントにご連絡ください。

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

>>:  平安クラウドの「魔法の武器」は企業のR&Dライフサイクル全体を完全に保護します

推薦する

ゲームコミュニティで生き残る方法についての簡単な講演

みなさんこんにちは。私は小さなウェブマスターです。以前は自分でゲームコミュニティを運営していました。...

半期レビュー: 2018 年の人気クラウド コンピューティング スタートアップ 10 社

成長を続けるクラウド スタートアップ企業の中で、際立っているのは、ハイパースケール コンピューティン...

#BlackFriday# 678CDN: 期間限定で50%オフ、アジア最速CDN(高防御を内蔵)、CC防御戦略のカスタマイズをサポート、新規ユーザーには100Gの高防御防御を提供

11月のゴールデンプロモーション月間に入りました。678cdnは「ブラックフライデー」をお届けします...

百度が週次トレンド分析を更新:中秋節と国慶節期間中は更新なし

本日、百度は金曜日の予定通り月例アップデートを行いました。お祭りごとに家族を恋しく思う気持ちが募り、...

検討すべき3つの主要なDockerの代替案

Docker は、コンテナ化されたアプリケーションを作成および管理するための一般的なプラットフォーム...

ウェブサイトのランキング最適化レッスン 2: SEO を実行するには? SEO を行うのは人間になるようなものです!

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスSEO をするにはどうす...

仮想化を学んだとしても、まだ分からないことがあります。

仮想化技術とはコンピュータにおける仮想化とは、サーバ、ネットワーク、メモリ、ストレージなど、コンピュ...

ecshop フルシリーズ バージョン ウェブサイトの脆弱性 リモート コード実行 SQL インジェクションの脆弱性

月収10万元の起業の夢を実現するミニプログラム起業支援プランecshopの脆弱性は、2018年9月1...

チャンネルAPPプロモーション運用詳細

概要: Android チャネル操作では何に注意すべきでしょうか? 1. チャンネルのゲームプレイと...

B2Bウェブサイトの新しいマーケティング戦略の簡単な分析:独立したマイクロブログマーケティング

従来のWeiboマーケティングは、ブランドプロモーション、イベント企画、個人イメージのパッケージ化、...

「Duoduo Orchard」はどのようにしてPinduoduoのゲーミフィケーション成長を実現するのでしょうか?

「多多果樹園」は、ピン多多が2018年4月にリリースしたカジュアルソーシャルゲームです。オンラインの...

SEOの考え方: 高いところにいるときだけ、遠くまでおしっこができる

中国の旧正月まであと1ヶ月ちょっとです。ここ数日、専門家は皆、Googleは長い間PRを更新しないだ...

ガートナーが「中国のクラウド セキュリティ市場の概要」を発表: クラウド セキュリティ開発が黄金時代を迎える過程を詳しく見る

最近、国際的に有名なコンサルティング組織であるガートナーは、中国のセキュリティ市場の調査と中国のセキ...

売り手のためのクイックルック: ポッドキャストのための 5 つの SEO ヒント

パンデミック中にポッドキャストを聴く人の数が劇的に増加し、ポッドキャストは2019年に主流のマーケテ...

2021年テンセントSTAC科学技術イノベーション合同会議が成都で開催:成都・重慶経済圏に統合し、人工知能人材高原を構築

この会議では、政府、企業、大学、業界の専門家を招き、マルチエージェントや画像認識などの人工知能の重要...