Java - JMM (上)

101 阅读3分钟

1. native method stacks

  本地方法栈,为虚拟机使用的native方法服务和虚拟机栈一样,本地方法栈也会抛出StackOverFlowError和OutOfMemoryError异常

2. Program Counter

  程序计数器,记录的是正在执行的虚拟机字节码指令的地址,可以看成是当前线程所执行的字节码的行号指示器,每个线程都有一个独立的程序计数器,计数器之间互不影响,独立存储,这类内存区域成为-线程私有内存。

3. method area

  方法区,各个线程共享的内存区域,用于存储已被虚拟机加载的类信息,常量、静态变量、即时编译器编译后的代码等数据,HotSpot虚拟机的设计团队把GC分代收集扩展至方法区,或者说使用永久代来代替方法区。
  JDK1.7的HotSpot中把放在永久代的字符从常量池移除,当方法区无法满足内存的分配需求时,抛出OutOfMemoryError。

4. JVM stacks

  java虚拟机栈,同程序计数器一样,也是线程私有的。每个方法在执行的时候都会创建一个栈帧、存储局部变量表,操作数栈、动态链接、方法出口等信息。
  每个方法从调用直至执行完成的过程,都对应一个栈帧在虚拟机中入栈和出栈的过程。
  局部变量表所需的内存空间在编译期间完成分配,方进入一个方法时,方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
  如果请求的栈深度超过虚拟机锁允许的深度,抛出StackOverFlowError。如果拓展无法申请到足够的内存,抛出OutOfMemoryError。

5. run-time constant pool

  方法区包含运行时常量池。
  运行时常量池,方法区的一部分,Class文件除了有类的版本、字段、方法、接口等描述信息外,还有常量池。存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放。
  运行时常量池相对于Class文件常量池具有动态性,运行期间也可以将新的常量放入常量池,比如Spring类的intern()方法。
  当运行时常量池无法申请到更多的内存时,抛出OutOfMemoryError。

6. heep

  Java堆是所有线程共享的一块内存区域,存放对象实例,几乎所有的对象实例都在这里分配。
  Java堆是垃圾回收的主要区域,采用分代收集算法。
  Java堆分为新生代和老年代,新生代分为Eden,From Survivor,To Survivor空间。
  堆中无法完成对象实例的内存分配,且堆也无法扩展时,将抛出OutOfMemryError。

7. 直接内存

  不是运行时区域的一部分。 JDK1.4加入NIO它可以使用Native函数库直接分配堆外内存,然后通过Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。
1566461693(1).png