プログラムカウンタ01、JVMのメモリモデル:プログラムカウンタ

01 - JVMのメモリモデル:プログラムカウンタ

 

A、JVMモデルの概要

  Javaプログラム中のJava仮想マシン(JVM)が実行されている、それはメモリ管理のこれらの領域を分割し、異なる領域の数にJVM起動時に作成されたデータといくつかのだろう、一部のユーザーがでスレッドを開始そして確立と破壊を終了します。メモリモデルは、基本的なJVMランタイムを、次のとおりです。

  図に示す「JAVA SE7」JVM仮想マシン仕様という。仮想マシンの仕様は静的ではなく、OracleのJAVAの新バージョンは、JVMはいくつかの最適化と改善を行う可能性があり、JDK8のバージョンでは、たとえば、メソッド領域は、メタスペース(メタデータによって取り外して交換されることに注意してくださいスペース)。

  このおよび以下のセクションでは、JDK7の標準は、ランタイムデータ領域の一例としてのJVMを説明するであろう。

第二に、プログラム・カウンタ(プログラムカウンタレジスタ)

2.1)プログラム・カウンタは何ですか

  プログラムカウンタは、現在のスレッドによって実行される行番号指示子記録バイトコードです。
  コードはJITなしにJavaバイトコードをコンパイルした後、その実装はによって解釈され、コンパイルする前に(時間コンパイラ)が経過「バイトコードインタプリタ。」シンプルな動作原理は、バイトコード命令を読み取るために、バイトコードインタプリタを読み取るためにメモリにロードされます。命令を読んだ後、命令は、固定された操作と分岐、ループ、ジャンプ及びこれらの操作に基づいて、他のプロセスへの「翻訳しました」。
  プログラムカウンタが余計な質問であれば、上記の説明から生成することができます。こうした流れは、分岐ジャンプの場合でも、ので、順次命令の実行に沿って進むと、指定された命令へのジャンプは、シーケンスプログラムの完全な実行を確保するために継続することです。プログラムは、常に一つのスレッドだけであると仮定すると、何の問題もなく、この質問は、それは、プログラムカウンタを必要としません。しかし、実際にはプログラムが実行の複数のスレッドによるコラボレーションです。
  まず、JVMのマルチスレッド実装を把握する必要があります。マルチスレッドは、CPU、ラウンドロビンアルゴリズムが実装されている(すなわち、交互スレッド及び割り当て処理の実行時間を切り替える)ことにより、JVMです。言い換えれば、スレッドが別のスレッドのタイムスライスを始めるためにしながら、実装プロセスに懸濁されたタイムスライスを使い果たす可能性があるため。プログラム・カウンタを通してスレッドを記録するために、それが最後のJVMで実行された場所を知ることが必要であるところから継続するために中断されたときに中断されたスレッドは、タイムスライスを再取得する場合バイトコード実行位置。したがって、プログラム・カウンタは、各スレッドが独自の独立したワークカウンタを有する単離されたスレッドを有する特性です。

2.2)プログラム・カウンタの特性

  1.糸分離、各スレッドは、独自の独立した作業カウンターを有します。
  (対策の説明を参照)。2.実行するJavaメソッドは、プログラムカウンタ値があり、記録が実行されるアドレスバイトコード命令です。
  3.ネイティブネイティブメソッドの実行、プログラムカウンタの値がヌル(未定義)です。ネイティブJNIメソッドを直接ローカルのJava、C / C ++ライブラリを介して起動されているので、約C / C ++メソッドを呼び出すために、このインターフェイスを呼び出すことにより、ネイティブメソッドC / C ++ Javaへの公開されたインターフェース、Javaのと同等とみなすことができます。C / C ++のJavaによる方法ので、代わりに実施すること。C / C ++実行は独自の言語によってではなく、JVMによって決定されたとき、それは、対応するバイトコード、およびメモリの割り当てを生成することはできませんので。
  4.プログラムカウンタのための小さなメモリ、計算中JVMメモリは、無視できます。
  プログラム・カウンタ、任意のOutOfMemoryErrorのJava仮想マシン仕様の所定の領域だけではなく。

A、JVMモデルの概要

  Javaプログラム中のJava仮想マシン(JVM)が実行されている、それはメモリ管理のこれらの領域を分割し、異なる領域の数にJVM起動時に作成されたデータといくつかのだろう、一部のユーザーがでスレッドを開始そして確立と破壊を終了します。メモリモデルは、基本的なJVMランタイムを、次のとおりです。

  上图展示的是“JAVA SE7”的JVM虚拟机规范。注意,虚拟机规范并不是一成不变的,Oracle在发布新的JAVA版本时,可能会对JVM做一定的优化和改进,例如在JDK8的版本中,方法区被移除,取而代之的是metaspace(元数据空间)。

  在本章及下面的章节中,将以JDK7的标准作为例子,对JVM的运行时数据区进行讲解。

二、程序计数器(Program Counter Register)

2.1)什么是程序计数器

  程序计数器是一个记录着当前线程所执行的字节码的行号指示器。
  JAVA代码编译后的字节码在未经过JIT(实时编译器)编译前,其执行方式是通过“字节码解释器”进行解释执行。简单的工作原理为解释器读取装载入内存的字节码,按照顺序读取字节码指令。读取一个指令后,将该指令“翻译”成固定的操作,并根据这些操作进行分支、循环、跳转等流程。
  从上面的描述中,可能会产生程序计数器是否是多余的疑问。因为沿着指令的顺序执行下去,即使是分支跳转这样的流程,跳转到指定的指令处按顺序继续执行是完全能够保证程序的执行顺序的。假设程序永远只有一个线程,这个疑问没有任何问题,也就是说并不需要程序计数器。但实际上程序是通过多个线程协同合作执行的。
  首先我们要搞清楚JVM的多线程实现方式。JVM的多线程是通过CPU时间片轮转(即线程轮流切换并分配处理器执行时间)算法来实现的。也就是说,某个线程在执行过程中可能会因为时间片耗尽而被挂起,而另一个线程获取到时间片开始执行。当被挂起的线程重新获取到时间片的时候,它要想从被挂起的地方继续执行,就必须知道它上次执行到哪个位置,在JVM中,通过程序计数器来记录某个线程的字节码执行位置。因此,程序计数器是具备线程隔离的特性,也就是说,每个线程工作时都有属于自己的独立计数器。

2.2)程序计数器的特点

  1.线程隔离性,每个线程工作时都有属于自己的独立计数器。
  2.执行java方法时,程序计数器是有值的,且记录的是正在执行的字节码指令的地址(参考上一小节的描述)。
  3.执行native本地方法时,程序计数器的值为空(Undefined)。因为native方法是java通过JNI直接调用本地C/C++库,可以近似的认为native方法相当于C/C++暴露给java的一个接口,java通过调用这个接口从而调用到C/C++方法。由于该方法是通过C/C++而不是java进行实现。那么自然无法产生相应的字节码,并且C/C++执行时的内存分配是由自己语言决定的,而不是由JVM决定的。
  4.程序计数器占用内存很小,在进行JVM内存计算时,可以忽略不计。
  5.程序计数器,是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError的区域。

おすすめ

転載: www.cnblogs.com/simonfblog/p/12003507.html