Java虚拟机内存结构
起源
1960年Lisp语言: 第一门真正使用内存动态分配和垃圾回收的语言。
运行时数据区域
1.程序计数器
Program Counter Register
1. 当前线程所执行的字节码的行号指示器。
2. 字节码解释器的工作是通过改变这个计数器的值去选取下一条需要执行的字节码指令。
3. 每条线程都一个独立的程序计数器。
4. 如果执行java方法,该位置记录正在执行的字节码指令地址,如果是native方法,该位置为空。
该部分是唯一不会OutOfMemory的部分。
2.Java虚拟机栈
Java Virtual Machine Stack
每一个方法从执行到完成的过程,对应着一个栈帧在虚拟机栈从入栈到出栈的过程。
局部变量表
编译期可知的各种数据类型、对象引用、returnAddress类型。
long、double占用2个局部变量空间(Slot)。局部变量空间大小在编译期确定。
StackoverflowError、OutofMemoryError
3.本地方法栈
Native Method Stack
4.Java堆
Java Heap
虚拟机管理的内存中最大的一块。
所有的对象实例和数组都在堆上分配。(例外:栈上分配、标量替换优化)
线程私有:分配缓冲区(Thread Local Allocation Buffer,TLAB)
5.方法区
Method Area
虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码。
运行时常量池
Runtime Constant Pool
该部分也需要内存回收,不过不是必要的。回收对象:Java中不再引用的实例
6.直接内存
Direct Memory
通过NIO函数写入读出的数据存于直接内存中。这部分的优点包括在JNI和java对象中传递的数据不需要在本地内存中和Java堆中移动。