プログラムカウンター
前書き
JVMのプログラムカウンタレジスタでは、レジスタの名前はCPUのレジスタに由来し、レジスタは命令に関連するオンサイト情報を格納します。CPUは、データをレジスタにロードすることによってのみ実行できます。ここでは、広義の物理レジスタではありませんが、PCカウンタ(または命令カウンタ)(プログラムフックとも呼ばれます)として変換する方が適切であり、不必要な誤解を招くことは容易ではありません。JVMのPCレジスタは、物理PCレジスタの抽象的なシミュレーションです。
それは小さなメモリスペースであり、ほとんど無視できます。また、最速のストレージ領域でもあります。
JVM仕様では、各スレッドには、スレッド専用の独自のプログラムカウンターがあり、そのライフサイクルはスレッドのライフサイクルと一致しています。
スレッドには常に1つのメソッド、いわゆる現在のメソッドしかありません。プログラムカウンタは、現在のスレッドによって実行されているJavaメソッドのJVM命令アドレスを格納します。または、ネイティブメソッドが実行されている場合は、未定義の値(未定義)です。
これは、プログラム制御フローの指標です。分岐、ループ、ジャンプ、例外処理、スレッド回復などの基本機能はすべて、完了するためにこのカウンターに依存する必要があります。バイトコードインタプリタが機能すると、このカウンタの値を変更して、実行する次のバイトコード命令を選択します。
これは、Java仮想マシン仕様でoutotMemoryError条件を指定しない唯一の領域です。
効果
PCレジスタは、次の命令、つまり実行される命令コードを指すアドレスを格納するために使用されます。実行エンジンは次の命令を読み取ります。
コードデモ
最初に簡単なコードを書きます
public class PCRegisterTest {
public static void main(String[] args) {
int i = 10;
int j = 20;
int k = i + j;
}
}
次に、コードがバイトコードファイルにコンパイルされます。再度確認すると、バイトコードの左側に行番号識別子があります。これは実際には命令アドレスであり、現在の実行を指すために使用されます。
0: bipush 10
2: istore_1
3: bipush 20
5: istore_2
6: iload_1
7: iload_2
8: iadd
9: istore_3
10: return
PCレジスタを介して、現在のプログラムが実行したステップを知ることができます。
PCレジスタを使用してバイトコード命令アドレスを格納する用途は何ですか?
CPUは常にスレッドを切り替える必要があるため、この時点で切り替えた後、実行を続行する場所を認識している必要があります。
JVMのバイトコードインタプリタは、PCレジスタの値を変更することにより、次に実行するバイトコード命令を決定する必要があります。
PCレジスタがプライベートに設定されているのはなぜですか?
いわゆるマルチスレッド方式では、特定の期間にスレッドの1つしか実行されないことは誰もが知っています。CPUは常にタスクを切り替えるため、必然的に頻繁な中断や回復につながります。スコアを確実にする方法正しい?各スレッドで実行されている現在のバイトコード命令アドレスを正確に記録するための最善の方法は、当然、各スレッドにPCレジスタを割り当てて、各スレッド間で独立した計算を実行できるようにすることです。相互干渉。
CPUタイムスライスの制限により、多くのスレッドの同時実行では、特定の瞬間に、マルチコアプロセッサのプロセッサまたはコアは特定のスレッドで1つの命令しか実行できません。
これは必然的に頻繁な中断または回復につながりますが、ポイントに違いがないことを確認するにはどうすればよいですか?各スレッドが作成されると、独自のプログラムカウンターとスタックフレームが生成され、プログラムカウンターはスレッド間で相互に影響を与えません。
CPUタイムスライス
CPUタイムスライスは、CPUによって各プログラムに割り当てられた時間です。各スレッドには、タイムスライスと呼ばれる期間が割り当てられます。
マクロレベル:ロシアは同時に複数のアプリケーションを開くことができ、各プログラムは矛盾することなく並行して実行されます。
ただし、ミクロレベルでは、CPUが1つしかないため、一度にプログラム要件の一部しか処理できません。公平性に対処する1つの方法は、タイムスライスを導入し、各プログラムを順番に実行することです。