Android学习java基础 集合 特性

JVM内存结构

2018-07-17  本文已影响381人  WJoe

JAVA内存区域

JVM在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区等。前三者为线程私有的,后两者为线程共享区域。

深入理解Java虚拟机(第二版)P39

1. 程序计数器(Program Counter Register)

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码行号指示器。
因为JVM的多线程是通过线程轮换并分配处理器执行时间来实现的,所以在任意时刻,一个处理器都只会执行一条线程中的指令。所以为了切换后能够恢复到正确的执行位置,每条线程都需要一个独立的计数器,它们互不影响。因此,程序计数器是线程私有的。
如果线程执行的是一个Java方法,计数器记录正在执行的虚拟机字节码指令的地址。如果是Native方法,能为空。

2. Java虚拟机栈(Java Virtual Machine Stacks)

Java虚拟机栈描述的是Java方法执行的内存模型: 每个方法执行的时候会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。一个方法从执行到返回,就对应一个栈帧在虚拟机栈中入栈和出栈的过程。

局部变量表

局部变量表存放的是编译期可知的各种基本数据类型、对象引用(reference类型)、returnAddress类型。其中64位长度的long和double类型数据会占用2个局部变量空间(Slot),其余只占用1个。局部变量表所需空间在变异期间完成分配,所以当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间完全确定,运行期间不会改变。

3. 本地方法栈(Native Method Stack)

本地方法栈和虚拟机栈的作用非常相似、区别在于一个执行的是Java方法,一个执行的是Native方法。
使用native关键字表示的方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由Java去调用。

4. Java堆(Java Heap)

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。这个内存区域的唯一目的就是存放对象实例以及数组。Java堆是垃圾收集器的主要区域。从内存回收的角度来看,现代收集器都是使用分代收集算法,所以可以细分为:新生代和老年代,新生代还可以分为Eden空间、From Survivor空间、To Survivor空间等。
Java堆的JVM参数主要是 -Xms和-Xmn。

5. 方法区(Method Area)

方法区和Java堆一样,是各个线程共享的内存区域,它被用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译期编译后的代码等数据

运行时常量池(Runtime Constant Pool)

运行时常量池是方法区的一部分。 Class文件中除了类的版本、字段、方法、接口等描述信息,还有常量池(Constant Pool Table),主要包括编译期生成的各种字面量(Literal)和符号引用量(Symbolic References)。字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。包括了如下三种类型的常量:

上一篇下一篇

猜你喜欢

热点阅读