JVM 仮想マシン スタックの概要

1.仮想マシンスタックの構造

Java 仮想マシン スタックは、初期には Java スタックと呼ばれていました. スレッドが作成されるたびに、対応する仮想マシン スタックが作成されます. そのライフ サイクルは、スレッドのライフ サイクルと一致しています. 仮想マシン スタックはスタック フレームで構成され、各スタック フレームはメソッドに対応し、メソッド呼び出しはスタック フレームがスタックにプッシュされることに対応し、メソッドが終了してスタック フレームがスタックからポップされます。スタック内の各スタック フレームは、ローカル変数テーブル、オペランド スタック、ダイナミック リンク、メソッド リターン アドレス、および追加情報で構成されます。スタックの構造は次のとおりです。

ここに画像の説明を挿入

2.仮想マシンスタックの特徴

  1. 仮想マシン スタックは、ストレージを割り当てるための高速かつ効果的な方法であり、そのアクセス速度はプログラム カウンターに次ぐものです。

  2. 仮想マシン スタックには、プッシュとポップの 2 つの操作しかありません。

    メソッド呼び出しはスタックにプッシュされ、メソッドの実行が終了するとメソッドがポップアウトされます。

  3. 仮想マシン スタックにガベージ コレクションの問題はありません

  4. 仮想マシン スタックには、次の 2 つの例外がある場合があります: StackOverFlowError、OutOfMemoryError

    仮想マシン スタックのサイズは、動的に設定することも、固定することもできます。スタック サイズが固定の場合、すべてのスタック フレーム サイズの合計がスタック サイズより大きい場合、またはスタック フレームがスタックより大きい場合、StackOverFlowError 例外が報告されます。スタック サイズが動的な場合、スタックは適用できません。より大きなスタック スペースの場合、またはメモリ サイズが新しいスタックを作成できない場合、OutOfMemoryError 例外が報告されます。

3. 仮想マシンスタックの動作原理

  • アクティブなスレッドでは、一度にアクティブにできるスタック フレームは 1 つだけです。現在実行中のメソッドに対応するスタック フレームのみが有効です. 現在有効なスタック フレームは現在のスタック フレーム (スタック トップ スタック フレーム) になり、現在のスタック フレームと呼ばれ、対応するメソッドは現在のメソッドと呼ばれます.このメソッドは、現在のスタック フレームと呼ばれます。
  • 現在のメソッドが他のメソッドを呼び出す場合、新しいスタック フレームが作成されてスタックにプッシュされ、新しい現在のスタック フレームになります。
  • 実行エンジンによって実行されるバイトコード命令は、現在のスタック フレームのみを対象としています。
  • 別のスレッドのスタック フレームを別のスレッドのスタック フレームで参照することはできません。
  • このメソッドには 2 つの return メソッドがあります。1 つは通常に戻る方法で、もう 1 つは例外をスローする方法で、どちらもスタック フレームがスタックから飛び出します。

次のコードは、メソッドの呼び出しとスタック フレームのアクティビティを示しています。

/**
 * @author cx
 * @date 2022/10/24
 */
public class StackDemo01 {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("main方法开始运行...");
        method1("main");
        System.out.println("main方法运行结束...");
    }

    static void method1(String name){
    
    
        System.out.println("method1被" +name+ "方法调用了..." );
        method2("method1");
        System.out.println("method1运行结束...");
    }

    static void method2(String name){
    
    
        System.out.println("method2被" +name+ "方法调用了..." );
        method3("method2");
        System.out.println("method2运行结束...");
    }

    static void method3(String name){
    
    
        System.out.println("method3被" +name+ "方法调用了..." );
        System.out.println("method3运行结束...");
    }

//    console:
//    main方法开始运行...
//    method1被main方法调用了...
//    method2被method1方法调用了...
//    method3被method2方法调用了...
//    method3运行结束...
//    method2运行结束...
//    method1运行结束...
//    main方法运行结束...
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/chenxingxingxing/article/details/127505416