JVM(A) - 実行時のメモリ構造

 

  JVMの実装で  のJava プロセスプログラムは、異なるメモリ領域に物理メモリを管理し、各領域は異なるデータが格納されているであろう。各領域は、異なる目的を持っているだけでなく、タイミングの創造と破壊、仮想マシンの規定によると、あなたは、このような得ることができますJVMのメモリ構造を。

1  プログラムカウンタ

  プログラム・カウンタ(プログラム カウンタ レジスタ)は、比較的小さなメモリ領域であり、現在のスレッドによって実行される行番号指示子バイトコードとみなすことができます。現在のスレッドのバイトコード命令を格納するための情報は、環状、分枝、次に実行されるべきである、異常、ジャンプ。任意の時点で、プロセッサが可能にするために、スレッド内の命令を実行することができるCPUの各スレッドように、タイム・スライスを、正常にコンテキストスイッチサイクルを行った後、正しい位置に戻し、各スレッドはそれ自身の別個のプログラムカウンタを有しています間には、お互いに影響を与えますので、このエリアには、JVMのスレッドのプライベートを設計されています。

  このメモリ領域は、で唯一のJava仮想マシン仕様のために用意されていませんOutOfMemoryErrorの地域の文脈。 

 2  Java仮想マシンのスタック

  与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,与线程的生命周期相同。虚拟机栈描述 Java方法执行的内存模型:每个方法在执行的同时都会创建一个独特的数据结构:栈帧(Stack Frame)。它主要用来存储局部变量表、操作数栈、动态链接、方法出口等信息。方法的调用就对应着栈帧在虚拟机栈中的压栈与出栈过程。

  每一个线程在创建的时候,JVM 都会为其创建对应的虚拟机栈,同等大小的虚拟机栈如果局部变量表等内存信息越小,则被压入的栈帧就会越多,反之被压入的栈帧就会越少,一般可以将栈帧内存的大小称为宽度,栈帧的数量称为虚拟机栈的深度。可以把一个虚拟机栈想象成为面积固定的长方形,宽就是栈帧内保存的信息的大小,长就是栈帧的数量,也就是虚拟机栈的深度,当宽变小了,那么长就变大了,所以可以压入更多的栈帧(当然一般虚拟机栈的内存大小是指出动态扩展的)。如果某一时刻一个线程请求的栈深度大于虚拟机所允许的栈深度,则会抛出 StackOverFlowError 异常;如果虚拟机可以动态扩展,扩展时无法申请到足够的内存,就会抛出 OutOfMemoryError 异常。

 3  本地方法栈

  本地方法栈(Native Method Stack)和虚拟机栈所发挥的作用很相似,都是线程私有的,都可以抛出 StackOverFlowError 异常 和 OutOfMemoryError 异常。他们之间的区别就是虚拟机栈为虚拟机执行 Java 方法(字节码)服务;本地方法栈则为虚拟机使用的 Native 方法服务。Java 中提供了调用本地方法的本地接口(Java Native Interface),是一些 C/C++ 程序,在线程的执行过程中,会经常碰到调用 JNI 方法的情况,比如网络通信、文件操作的底层等。

 4  Java 堆

  堆内存是 JVM 所管理的内存中最大的一块(从我画的情况来看,看的出来对吧)。堆内存是被所有线程所共享的一块内存区域,在虚拟机启动的时候创建。堆和栈是我们在刚接触编程的时候最容易遇到,也是醉容易搞混的两个概念,他们有的时候可以代表数据结构中的堆(就是可以实现最小二叉堆的那个)和栈(就是 FILO 那个),有的时候是表示内存的结构,所以千万不要搞混了。经常有人把 Java 内存分为堆内存和栈内存,就是指的这里的Java堆内存和虚拟机栈内存。但这种分法是比较粗糙的,所以我们还是需要学习更加细腻的分法呀。

  堆内存被用来存放对象的实例和数组对象,就是 new 出来的那些对象。

  此外,堆内存还是垃圾收集器管理的主要区域,具体的垃圾回收内容我们后面再仔细研读研读。因此很多时候也被称为“GC堆”(Garbage Collected Heap)。从垃圾回收的角度看,现在的垃圾收集器基本都会采用分代收集算法,所以堆内存还可以被分为:新生代和老年代,更细致的可以分为 Eden 区、From Survivor 空间、To Surviver 空间等。

  当在堆中没有内存完成分配实例,并且堆也无法完成扩展时,将会抛出 OutOfMemoryError 异常。

5  方法区

  方法区(Method Area)和堆内存一样,是所以线程共享的内存,主要用来存储已被 JVM 加载的类信息、常量、静态变量、即时编译器(Just In Time,JIT)编译后的代码等数据。在 HotSpot 虚拟机里,垃圾收集分代收集扩展到了方法区。HotSpot 的垃圾收集器可以像管理 Java 堆一样管理这部分内存,但是对于其他虚拟机来讲,可以不实现这样,甚至可以选择不进行垃圾回收。

  运行时常量池(Runtime Constant Pool)是方法区的一部分。用来存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的允许时常量池中存放。既然有内容,那肯定也需要被 GC了,回收的主要目标也就是针对常量池的回收以及对类型的卸载。但是这个区的回收效果比较难以让人满意,容易因为此区域内存没有完全回收而造成内存泄漏。

  同样,根据 Java 虚拟机规定,当方法区无法满足内存分配需求时,将会抛出 OutOfMemoryError 异常。

 

 

 

 

おすすめ

転載: www.cnblogs.com/dogeLife/p/11361230.html