JVMの基本概念 JVM の中国語名は Java Virtual Machine であり、ソフトウェア技術によってシミュレートされた仮想コンピュータです。 JVM は翻訳者としても機能します。私たちが作成した Java プログラムは、オペレーティング システムによって直接認識されることはありません。このとき、JVM の役割が反映されます。プログラムをシステムに変換し、プログラムが実行する必要がある操作をシステムに伝える役割を担います。 Java プログラムは、JVM が認識して実行する前に、コンパイルして .Class ファイルを生成する必要があることは誰もが知っています。 JVM は各オペレーティング システムに対応するインタープリターを開発するため、オペレーティング システムに JVM の対応するバージョンがあれば、コンパイルされた Java コードを実行できます。これが、Java が一度コンパイルされればどこでも実行できる理由です。 JVM ライフサイクル JVM は、Java プログラムの実行が開始されると実行され、プログラムが終了すると停止します。 Java プログラムは JVM プロセスを開始します。マシン上で 3 つのプログラムが実行されている場合、実行される JVM プロセスは 3 つになります。 JVMにはデーモンスレッドと通常のスレッドの2種類のスレッドがあります。 デーモン スレッドは、ガベージ コレクション (GC) など、JVM 自体によって使用されるスレッドです。 通常スレッドは、一般的に Java プログラムのスレッドです。 JVM 内で通常のスレッドが実行されている限り、JVM は停止しません。 十分な権限がある場合は、exit() メソッドを呼び出してプログラムを終了できます。 JVM構造システム JVM 起動プロセス 1. JVMの読み込み環境と構成 これを学ぶ前に、JDK と JRE の違いについて理解しておく必要があります。 JDK は開発者向けの SDK です。 Java 開発環境とランタイム環境を提供します。 JDK には JRE が含まれています。 JRE は Java ランタイム環境であり、開発者を含むすべての Java プログラム ユーザーを対象としています。 JRE = ランタイム環境 = JVM。 JDK がインストールされている場合、コンピューターに 2 つの JRE が存在します。1 つは /Java/jre.../ にあり、もう 1 つは /Java/jdk.../jre にあります。そこで疑問になるのが、マシン上に 2 つ以上の JRE がある場合、どれを実行するかを誰が決めるのかということです。このタスクは java.exe が担当し、java.exe のタスクは Java プログラムを実行するための適切な JRE を見つけることです。 java.exe は次の順序で JRE を選択します。
これらの手順の主な中核は、JVM の絶対パスを見つけることです。 jvm.cfg のパスは次のとおりです: JRE パス\lib"CPU アーキテクチャ"\jvm.fig jvm.cfg の内容は次のとおりです。
KNOWNは存在する、IGNOREは存在しない、ALIASED_TOは別のJVMに別名を付与することを意味する。 WARNは存在しない場合に代替品を探すことを意味し、ERRORは存在しない場合に例外をスローすることを意味します。 2. JVMをロードする 最初のステップで JVM のパスを見つけた後、Java.exe は LoadJavaVM を通じて JVM ファイルをロードします。 LoadLibrary は、JVM ダイナミック リンク ライブラリをロードし、JVM 内の外部関数 JNI_CreateJavaVM および JNI_GetDefaultJavaVMIntArgs を InvocationFunction 変数の CreateJavaVM および GetDefaultJavaVMInitArgs 関数ポインター変数にフックします。 JVMのロードが完了しました。 3. JVMを初期化し、ローカル呼び出しインターフェースを取得する JVM の JNI_CreateJavaVM メソッドである InvocationFunction -> CreateJavaVM を呼び出して、JNIEnv 構造体のインスタンスを取得します。 4. Javaプログラムを実行する JVMがJavaプログラムを実行するには、jarパッケージとクラスの2つの方法があります。 jar を実行すると、Java.exe は GetMainClassName 関数を呼び出します。この関数は、最初に JNIEnv インスタンスを取得し、次に JarFileJNIEnv クラスの getManifest() を呼び出し、返された Manifest オブジェクトから getAttrebutes("Main-Class") の値を取得します。つまり、jar パッケージ内のファイル META-INF/MANIFEST.MF で実行されるメイン クラスとして指定されている Main-Class のメイン クラス名を取得します。次に、メイン関数は Java.c の LoadClass メソッドを呼び出してメイン クラスをロードします (JNIEnv インスタンスの FindClass を使用)。 クラスを実行すると、メイン関数は Java.c の LoadClass メソッドを直接呼び出してクラスをロードします。 クラスファイル クラス ファイルは Java コンパイラによって生成されます。作成した .Java ファイルは、コンパイラを通過すると .Class ファイルになり、JVM によって認識され、実行されるようになります。 クラスローディングサブシステム クラス ローディング サブシステムは、クラス ローダーとも呼ばれます。 JVM はデフォルトで 3 つのクラス ローダーを提供します。 1. BootStrap ClassLoader: ブート クラス ローダーと呼ばれます。これはトップレベルのクラスローダーであり、rt.jar、resources.jar、charsets.jar などの JDK のコアクラスライブラリをロードする役割を担います。 2. 拡張クラスローダー: 拡張クラスローダーと呼ばれ、Java 拡張クラスライブラリのロードを担当します。デフォルトでは、$JAVA_HOME または -Djava.ext.dirs で指定されたディレクトリの jre/lib/*.jar にある jar パッケージがロードされます。 3. App ClassLoader: これはシステム クラス ローダーと呼ばれ、アプリケーションのクラスパス ディレクトリ内のすべての jar ファイルとクラス ファイルをロードする役割を担います。 Java がデフォルトで提供する 3 つの ClassLoader (ローダー) に加えて、独自のニーズに応じて ClassLoader をカスタマイズすることもできます。カスタム ClassLoader は java.lang.ClassLoader クラスを継承する必要があります。 BootStrap ClassLoader に加えて、他の 2 つのデフォルト ローダーは java.lang.ClassLoader から継承されます。 BootStrap ClassLoader は通常の Java クラスではありません。これは C++ で記述され、JVM のカーネルに組み込まれています。 JVM が起動すると、BootStrap ClassLoader も起動されます。コア クラス ライブラリをロードし、Extension ClassLoader および App ClassLoader クラス ローダーを構築する役割を担います。 クラス ローダー サブシステムは、クラス ファイルの検索と読み込みを担当するだけでなく、次の手順に厳密に従って多くの処理を実行します。
方法領域 JVM では、型情報とクラスの静的変数はメソッド領域に格納されます。型情報は、クラスのロード プロセス中にクラス ローダーによってクラス ファイルから抽出されます。 注意すべき点は、定数プールもメソッド領域に格納されることです。 プログラム内のすべてのスレッドはメソッド領域を共有するため、メソッド領域内の情報へのアクセスはスレッドセーフである必要があります。 2 つのスレッドが同時にクラスをロードしようとすると、1 つのスレッドのみがクラスをロードでき、もう 1 つのスレッドは待機する必要があります。 プログラム実行中にメソッド領域のサイズを変更したり、プログラム実行中にプログラムを拡張したりすることができます。 メソッド領域もガベージコレクションの対象となりますが、条件は非常に厳格です。クラスへの参照がない場合に必要です。 タイプ情報には何が含まれますか? 1. 型の完全修飾名 2. 型の直接のスーパークラスの完全修飾名(スーパータイプがない場合、またはスーパータイプが java.lang.Object の場合を除く) 3. 型がクラスであるかどうか 4. 型の修飾子 (public、private、protected、static、final、volatile、transient など) 5. 直接スーパーインターフェースの完全修飾名の順序付きリスト 6. タイプのフィールド情報 7. タイプのメソッド情報 8. 型内で宣言されたすべてのクラス(静的)変数(定数を除く) 9. クラスClassLoaderへの参照 10. クラスへの参照 Class 11. 型の定数プール メソッドテーブル メソッド領域に格納されているすべてのデータに効率よくアクセスするために、上記の種類の情報を格納することに加えて、アクセスを高速化するように設計されたデータ構造、つまりメソッド リストも存在します。ロードされる非抽象クラスごとに、Java 仮想マシンはそれらのメソッド リストを生成します。このリストには、このクラスによって呼び出される可能性のあるすべてのインスタンス メソッドへの参照と、親クラスで呼び出されるメソッドが格納されます。 Java ヒープ (JVM ヒープ、ヒープ) Java がクラスのインスタンス オブジェクトまたは配列を作成すると、ヒープ内の新しいオブジェクトにメモリが割り当てられます。 仮想マシンにはヒープが 1 つだけ存在し、プログラム内のすべてのスレッドがそれを共有します。 ヒープは最も多くのメモリ空間を占有します。 ヒープのアクセス タイプはパイプライン タイプ、先入先出です。 プログラムの実行中に、ヒープのメモリ サイズを動的に割り当てることができます。 ヒープのメモリ リソースの回復は JVM GC によって管理されます。 Java スタック (JVM スタック、スタック) 基本データ型とカスタム オブジェクトへの参照のみが Java スタックに保存されます。これはオブジェクトへの参照のみであり、オブジェクト自体ではないことに注意してください。オブジェクトはヒープ領域に保存されます。 拡張知識: String、Integer、Byte、Short、Long、Character、および Boolean は、ヒープ内に格納されるパッケージ タイプです。 スタックのアクセス タイプは、水カップのアクセス タイプ、つまり先入れ後出しに似ています。 スタック内のデータは、そのスコープを超えると自動的に解放され、JVM GC によって管理されません。 各スレッドにはスタック領域が含まれており、各スタック内のデータはプライベートであり、他のスタックからアクセスすることはできません。 各スレッドは操作スタックを確立し、各スタックには複数のスタック フレームが含まれ、各スタック フレームは各メソッドの各呼び出しに対応し、各スタック フレームには次の 3 つの部分が含まれます。 ローカル変数領域(メソッド内の基本型変数、変数オブジェクトポインタ) オペランドスタック領域(メソッド実行中に生成された中間結果を格納する) ランタイム環境領域(動的接続、関連情報を返す正しい方法、例外のキャプチャ) |
<<: この記事を読んでも、JVM のクラス ローディング メカニズムがまだ理解できませんか?
>>: Kubernetes を簡単に学ぶにはどうすればいいですか?
エッジコンピューティングについては何度も話してきました。おそらく、2018 年以降、エッジとクラウド...
[[399065]]この記事ではいくつかの原則とアイデアを紹介するだけですが、皆さんのお役に立てれば...
[[416383]]いわゆる変革とは、構造形態、運営モデル、人々の物事に対する概念の根本的な変化のプ...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています電子メール...
AWS EC2 (正式名称は Amazon Elastic Compute Cloud) は、クラウ...
Racknerdは、新しい高帯域幅サーバー+無制限トラフィックサーバーをリリースしました。1台のマシ...
Cubecloud は、市場で最も手頃な香港 cn2gia vps の 1 つであり、最大の帯域幅 ...
Googleは2年前から中国市場からの撤退を検討し始めていたが、中国におけるインターネットの需要が非...
鉄道局は昨日から、9月30日の中秋節の切符をインターネットと電話で販売し始めた。上海駅の予測によれば...
Akkocloud German VPS は新しいパッケージを開始しました。3 つのネットワーク、c...
[[422686]]リフレクションは Java 言語の非常に重要な機能であり、実行中の Java プ...
timeweb (登録商標 N461919、ライセンス ROSKOMNADZOR N142739) ...
自動車は家庭にとって生活必需品となり、それを支える設備も販売のホットスポットとなっています。自動車B...
1. タオバオはブラックリスト機能を導入し、悪質な購入者はブラックリストに登録される可能性がある6月...
[[422238]]単一のアプリケーションと環境複数のアプリケーションと環境CI 継続的インテグレー...