Java运行时数据区和线程栈

Java运行时数据区和线程栈

Java运行时数据区

上图是Java运行时数据区的逻辑图,之因此说是逻辑图,那是由于虚拟机规范只是描述虚拟机包含方法区、堆、Java栈、PC寄存器、本地方法栈,实现者只要实现虚拟机的功能便可,由于虚拟机规范没有明确指定这几个数据区的从属和包含关系。数组

方法区(Method Area)

    关于堆的描述,咱们直接引用虚拟机规范《The Java® Virtual Machine Specification Java SE 8 Edition》2015-02-13版本,2.5.4节多线程

    “The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It stores per-class structures such as the run-time constant pool,field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.”并发

    方法区共享于Java线程。方法区用于存储:类的结构、运行时常量池、字段、方法数据、构造方法和普通方法的字节码内容、特殊方法。spa

    方法区的类结构、字段等信息在,在类型加载时获得,并存储到到方法区的。虽然方法区共享于Java线程,但类加载阶段只能是单线程进行,因此在类加载阶段不存在并发的状况。因为类的静态变动也存储在方法内,因此类的静态变量在使用过程当中是须要注意共享的问题的。线程

    方法区也存在也须要进行内存管理(即垃圾回收),由实现虚拟者选择具体的技术。方法区是一个逻辑区,因此方法区能够是独立于堆的内存,也能够是堆中划分出来的一部分,这个最决于虚拟机实现者具体实现和版本。指针

    常量池就是该类型的直接常量和其它类型的字段、方法的符号引用。虚拟机必须为每一个被加载的类型维护一个常量池。常量池也属于方法区的中一部份内容。code

堆(Heap)

    关于堆的描述,咱们直接引用虚拟机规范《The Java® Virtual Machine Specification Java SE 8 Edition》2015-02-13版本,2.5.3节对象

    “The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.”内存

    首先,Heap共享于全部Java线程,而后用于分配类实例和数组内存。通俗点解释就是:一个Java虚拟机实例只有一个堆,用于存储类实例和数组,而且堆是线程共享的。这就很好解释了多线程共享堆数据要经过使用同步规则控制的缘由了。ci

    “Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector);”

    规范明确虚拟机的实现要一套自动管理系统管理存储的对象,即垃圾回收机制。但Java虚拟机并指明具体使用那些技术去管理对象的回收,虚拟机的实现者可使用任意技术进行回收。甚至极端状况下,能够不释放所持有的对象,直接抛异常,由于这也是一种对象管理方式。

Java栈(Java Virtual Machine Stacks)

    Java线程栈的描述,咱们直接引用虚拟机规范《The Java® Virtual Machine Specification Java SE 8 Edition》2015-02-13版本,2.5.2节

    “Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.”

     Java线程栈从线程建立时存在,而且是私有的。线程栈用户存储栈帧,栈帧用于存储局部变量、中间运算结果。因此局部是不存在并发的问题,由于每一个栈是私有的。

     Java线程栈属于一个逻辑栈,和方法区同样,由虚拟机的实现决定栈的位置,多是堆的一部分,也多是单独栈区。

      虚拟机只会对Java栈进行二种操做:以栈帧为单位的压栈和出栈。栈帧由:局部变量区、操做数栈、帧数据区。

PC寄存器(The pc Register)

    每一条Java虚拟机线程都有本身的PC寄存器。若是这个方法不是本地方法的,那PC寄存器就保存Java虚拟机正在执行的指令的地址,若是该方法是本地的,那PC寄存器的值是undefined。PC寄存器的容量能够存储一个returnAddress类型的数据或者一个本地指针。

本地方法栈

    线程进入使用Java之外的语言编写的方法,进入本地方法栈。本地方法不受虚拟机约束,能够实现作它任何想作的事情。具体由本地方法实现决定。另外本地方法栈还能够再回到Java方法中,再一次进入Java线程栈。

Java的线程与栈帧

    假设咱们的代码以下图所示,方法test调用方法add,其中方法add把两个参数相加,并返回结果。

    每当Java线程调用方法时,虚拟机就在Java线程栈中压入一个帧,方法return或方法抛出异常时弹出栈。当线程从test方法调用add方法时,压入add方法栈帧,则当前栈帧add帧。执行add方法后,返回结果并弹出当前帧,而后test方法的栈帧成了当前帧。

相关文章
相关标签/搜索