JVM には、基本型と参照型の 2 種類のデータ型が含まれています。 基本的な型には、数値型、ブール型、returnAddress 型が含まれます。 数値型には、整数型、浮動小数点型、char 型が含まれます。 ブール型にも true と false のみがあります。 returnAddress 型は JVM 命令のオペコードへのポインターであり、Java には対応する型はありません。 ブール型の演算は int 型の演算に変換され、ブール配列はバイト配列として演算されます。 1 は真、0 は偽を意味します。 参照型には、クラス型、配列型、インターフェース型の 3 種類があります。 それらの値は、動的に作成されたクラスインスタンス、配列、またはインターフェースを実装するクラスインスタンスです。 配列にはコンポーネント型と要素型があります。コンポーネント型は、配列の最も外側の次元を削除した後に残る型であり、まだ配列型である可能性があります (多次元配列の場合)。 要素型は、配列に格納される最小のデータ型です。基本型、クラス型、またはインターフェース型である必要があります。 1 次元配列の場合、コンポーネントの型と要素の型は同じです。 参照型には、オブジェクトが参照されていないことを意味する特別な値 null もあります。 ランタイムパブリックデータ領域 ヒープ jvm には、すべての jvm スレッド間で共有されるヒープがあります。ヒープは、クラス インスタンスと配列に割り当てられるすべてのメモリが取得される実行時データ領域です。 ヒープは JVM の起動時に作成されます。ヒープ内のオブジェクトは明示的に解放する必要はなく、GC はメモリの解放とリサイクルに役立ちます。 方法領域 jvm には、すべての jvm スレッド間で共有され、各クラスの構造を格納するメソッド領域があります。 ランタイム定数プール、フィールドとメソッドのデータ、メソッドとコンストラクターのコード、クラスとインスタンスの初期化、およびインターフェースの初期化のための特別なメソッドなど。 メソッド領域は論理的にはヒープ領域の一部ですが、JVM の起動時に作成されます。 ただし、単純な実装では、GC と圧縮を実行しないことも選択できます。この仕様では、メソッド領域の場所を必須にしておらず、コンパイルされたコードを管理するための戦略も必要としません。 ランタイム定数プール ランタイム定数プールは、クラスまたはインターフェースのバイトコード ファイル内の定数プールのランタイム表現であり、複数の定数が含まれています。 たとえば、コンパイル時にわかっている数値リテラル値や、実行時に解決する必要があるメソッドやフィールドへの参照など、ランタイム定数プールは従来の言語のシンボル テーブルと同様に機能しますが、含まれるデータはより広範囲にわたります。 ランタイム定数プールは、JVM のメソッド領域に割り当てられます。クラスまたはインターフェースのランタイム定数プールは、クラスまたはインターフェースが JVM によって作成されるときに構築されます。 ランタイムプライベートデータ領域 PCレジスタ JVM は一度に複数のスレッドの実行をサポートします。各スレッドには独自の PC レジスタがあります。スレッドは一度に 1 つのメソッドのコードのみを実行できます。 メソッドがネイティブでない場合、pc レジスタには現在実行中の jvm 命令のアドレスが含まれます。メソッドがネイティブの場合、pc レジスタの値は未定義になります。 JVMスタック 各 JVM スレッドには、スレッドの作成時に作成されるプライベート JVM スタックがあります。スタックにはフレームが格納されます。 jvm スタックは、C などの従来の言語のスタックに似ています。ローカル変数と一部の計算結果を保存し、メソッドの呼び出しと戻りに関与します。 jvm スタックは主にフレームのポップとプッシュに使用され、他の操作はありません。 フレームはヒープ上に割り当てられる可能性があるため、JVM スタックによって使用されるメモリは連続している必要はありません。 ネイティブメソッドスタック ネイティブ メソッドは Java で記述されていないため、ネイティブ メソッドをサポートするには C 言語スタックなどの従来のスタックが必要です。ただし、JVM はネイティブ メソッドをロードできないため、ネイティブ メソッドに必要なスタックを提供する必要はありません。 フレーム メソッドが呼び出されるたびに、新しいフレームが作成されます。メソッド呼び出しが完了すると、正常に完了するか例外をスローするかに関係なく、対応するフレームが破棄されます。 したがって、フレームはメソッド呼び出しの特定の形式であり、またはメソッド呼び出しがフレームの形式で実行されます。フレームは、データと部分的な計算結果を保存し、動的リンク、メソッドの戻り値、例外の配布を実行するために使用されます。 フレームは、フレームを作成したスレッドの JVM スタックに割り当てられます。各フレームには、独自のローカル変数配列、独自の操作データ スタック、および現在のメソッドが配置されているクラスのランタイム定数プールへの参照があります。 ローカル変数配列とオペランド スタックのサイズはコンパイル時に決定されます。これらは、フレームに関連付けられたメソッドのコンパイル済みコードとともに提供されます。したがって、フレーム データ構造のサイズは JVM 実装のみに依存します。これらの構造体に必要なメモリは、メソッドが呼び出されるときに同時に割り当てることができます。 スレッドの実行中は常に、 1 つのフレームだけがアクティブになります。このフレームは現在のフレームと呼ばれ、対応するメソッドは現在のメソッドと呼ばれ、メソッドが配置されているクラスは現在のクラスと呼ばれ、このとき使用されるローカル変数配列とオペランドスタックも現在のフレームのものです。 フレームのメソッドが別のメソッドを呼び出したり、そのメソッドが終了したりすると、フレームは現在のフレームではなくなります。 メソッドが呼び出されると、新しいフレームが作成され、実行制御が元のメソッドから新しいメソッドに移されると、この新しいフレームが現在のフレームになります。 メソッドが返されると、現在のフレームはメソッド実行の結果を前のフレームに渡し、前のフレームがアクティブになると現在のフレームは破棄されます。 ローカル変数配列 各フレームには変数配列が含まれており、ここによく知られているローカル変数が格納されます。このローカル変数配列の長さはコンパイル時に決定され、コンパイルされたメソッド コードとともに提供されます。 通常、1 つのローカル変数 (位置) に 1 つの型の値を格納できますが、long 型と double 型では 1 つの値を格納するために 2 つのローカル変数 (位置) が必要です。 ローカル変数はインデックスによってアドレス指定され、最初のローカル変数のインデックスは 0 になります。Long と double には 2 つの連続したインデックスが必要ですが、小さい方のインデックスに従ってアドレス指定されます。大きなインデックスに従ってデータを読み取ることはできませんが、書き込むことはできます。もちろん、これによってローカル変数の内容が台無しになります。 メソッドが呼び出されると、JVM はローカル変数を使用して渡されたパラメータ値を受け取ります。クラス (静的) メソッドが呼び出されると、すべての引数はインデックス 0 から始まるローカル変数の連続した配列に渡されます。 インスタンス (非静的) メソッドが呼び出されると、メソッド呼び出しが実行されているオブジェクトへの参照 (Java では this) とともにインデックス 0 が常に渡され、すべてのパラメーターは 1 から始まる一貫したローカル変数配列で渡されます。 オペランドスタック 各フレームには、実行中の jvm 命令のオペランドを格納するための後入れ先出しスタック (よく知られているオペランド スタック) が含まれています。このスタックの最大深度はコンパイル時に決定され、コンパイルされたメソッド コードとともに提供されます。 フレームが作成されると、オペランド スタックは空になります。 JVM は、定数値、ローカル変数値、フィールド値をオペランド スタックにロードするためのいくつかの命令を提供します。その他の JVM 命令は、オペランド スタック上のオペランドを使用して操作を実行し、結果をオペランド スタックに戻します。 オペランド スタックは、メソッド呼び出しに渡されるパラメーターを準備したり、メソッド呼び出しによって返される結果を受け取ったりするためにも使用されます。 long 型と double 型の値はスタック深度の 2 単位を占め、その他の型の値はスタック深度の 1 単位を占めます。 動的リンク 各フレームには、現在のメソッドの型のランタイム定数プールへの参照が含まれています。目的は、メソッド コードの動的リンクをサポートすることです。メソッド参照、呼び出されるメソッド、クラス ファイル内でアクセスされる変数を記述するコードは、シンボリック参照の形式で実装されます。 シンボリック参照の形式は、大まかに文字列の形式と考えることができます。つまり、文字列は、どのクラスのどのメソッドを呼び出す必要があるか、またはどのフィールドまたは変数にアクセスする必要があるかを示すために使用されます。シンボル参照の名前と同様に、これらは単なるシンボルであり、特定の値を取得できないため、変換する必要があります。 動的リンクは、これらのシンボリック メソッド参照を特定のメソッド参照に変換し、必要に応じてクラスをロードして不明瞭なシンボルを解決し、シンボリック変数アクセスを実行時にこれらの変数が配置されているストレージ構造の適切なオフセット (インデックス) に変換します。このアプローチは遅延バインディングとも呼ばれます。 メソッド呼び出し メソッド呼び出しが正常に完了すると (つまり、例外がスローされない場合)、返される値の型に基づいて適切な戻り命令が実行され、現在のフレームはローカル変数やオペランド スタックを含む呼び出し元の状態を復元し、呼び出し元のプログラム カウンターが適切に増加して、現在のメソッド呼び出し命令をスキップします。 戻り値は呼び出し元フレームのオペランド スタックに配置され、呼び出し元メソッドのフレームで実行が続行されます。 メソッドが呼び出されたときに例外がスローされ、その例外がメソッド内でキャッチおよび処理されない場合、メソッド呼び出しは突然終了します。この場合、メソッドの呼び出し元に値は返されません。 特別な方法 JVMレベルでは、Javaで書かれたすべてのコンストラクタは特別な名前を持つインスタンス初期化メソッドとして現れます。 インスタンス初期化メソッドは、invokespecial 命令を使用して JVM 内でのみ呼び出すことができ、まだ初期化されていないクラス インスタンスでのみ呼び出すことができます。 クラスまたはインターフェースには、最大 1 つのクラスまたはインターフェース初期化メソッドを含めることができ、このメソッドを呼び出すことによって初期化されます。クラスやインターフェースの初期化メソッドにも特別な名前があり、 メソッド名もコンパイラによって提供されます。 Java 7 以降では、このメソッドはバイトコード内で static としてマークする必要があります。 この初期化メソッドは、jvm によって暗黙的に呼び出されます。これらは、JVM 命令によって直接呼び出されることはありませんが、クラス初期化プロセスの一部として間接的にのみ呼び出されます。 Java クラス ライブラリ jvm は、Java クラス ライブラリの実装に対して適切なサポートを提供する必要があります。クラス ライブラリ内の一部のクラスは、JVM の支援なしでは実装できません。 リフレクションとは、フィールド情報、メソッド情報、コンストラクタ情報、親クラス情報、実装されたインターフェース情報など、クラスの型関連情報を実行時に取得することです。 このすべての情報は、クラスがロードされた後にのみ認識され、JVM のみがクラスをロードできます。 java.lang.reflect パッケージの下のクラスや Class クラスなど。 Java では、クラスまたはインターフェースはクラス ローダー (ClassLoader) を使用してロードされますが、実装は依然として JVM に委任されています。 クラスまたはインターフェースをリンクして初期化します。 セキュリティ (java.security パッケージの下のクラスや、SecurityManager などの他のクラスなど)。 Thread クラスなどのマルチスレッド。 java.lang.ref パッケージ内のクラスなどの弱参照。 パブリックデザイン、プライベート実装 上記の内容は、JVM の「比較的広範な」仕様にすぎません。実装計画や実装の詳細ではありません。 実装者は独自のニーズに応じて JVM を実装できます。たとえば、バックエンド サーバーで実行されている JVM とモバイル デバイスで実行されている JVM では、重点が確実に異なります。 Java を扱う人なら誰でも、JVM には実際には多くの実装バージョンがあることを知っています。 JVM は Java 言語とオペレーティング システムの間にあるため、上位の Java をサポートし、下位のオペレーティング システムと適切に対話する必要があります。 最後に ファイル操作、ネットワーク操作、メモリ操作、スレッド操作、I/O操作など、高級言語(Java、C#)における多くの操作は、高級言語自体では実装できません。 これは、仮想マシン (JVM、CLR) では実現できないものです。実際、これらはシステム リソースであり、オペレーティング システムだけがアクセスできるため、最終的にはオペレーティング システムによって実装されます。 Java または C# コードを使用してファイルを作成する場合、そのファイルが Java または C# によって作成されたとは考えないでください。彼らは、オペレーティング システム API をレイヤーごとに呼び出し、次にファイル システム API を呼び出し、最後にディスク ドライバーを呼び出しました。 このことから、言語を設計するには、キーワード、構文、コンパイラ、クラス ライブラリ、仮想マシンなどだけでなく、オペレーティング システム、さらには CPU アーキテクチャや CPU 命令セットなどのハードウェアに対する深い理解も必要であることがわかります。 そのため、言語に関連するすべてのことは非常に面倒で複雑であり、研究には多くの人的資源、資金、時間が必要です。結局、研究が成功してもエコシステムが存在せず、誰も使わないので、当然お金を稼ぐことは不可能です。 したがって、中国人はまだ独自の言語を持っていません。 |
<<: エッジコンピューティングが仕事を楽にする 5 つの方法
>>: エッジからリードする: エッジ コンピューティングがマイクロデータ構造に革命をもたらす方法 - クラウド コンピューティング セミマンスリー第 68 号
マーケティング業界の伝説的人物である石玉竹は、「巨人」、「美百品」、「黄金パートナー」などを通じて、...
達人とは、たとえ誰かが知っていることをあなたに伝えたとしても、あなたがそれを学ぶことができない人です...
NAV Communications は 1997 年に設立されたルーマニアの会社で、ドメイン名、仮...
月収10万元の起業の夢を実現するミニプログラム起業支援プラン何らかの理由で、最近多くの友人がRuFe...
Henghost の米国データセンターは、Henghost の 2 番目の主要なコンピューター ルー...
360統合検索は今年8月16日にリリースされると、360製品の巨大なユーザーベースにより、あっという...
1. ボトムインターレースバック接続初期のSEO担当者の多くがこれを行っていたのは、検索エンジンの初...
質問1:iOSチャネルをどこで利用すればよいかわかりません。Androidユーザーはオンラインになっ...
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス2019年、李佳琦や魏亜...
Buyvmのバーチャルホストbuyshareは少なくとも半年前から在庫切れでした。buyvmのバーチ...
ある男がフォーラムを開設し、毎月カードを発行したり大口顧客に割引を提供したりして、ネガティブな話を作...
Increhost は、高品質の KVM VPS、3 つのデータセンターを提供しており、価格もかなり...
ウェブマスター統計ツールは、ほぼすべてのウェブマスターが知って理解しなければならないツールです。現在...
第二世代の百度緑大根アルゴリズムはウェブサイトの外部リンクに多くの要件を課していますが、これらの要件...
vpsunlimited は 2010 年に設立され、主に XEN ベースの VPS サービスを提供...