Java运行时内存区域
程序计数器(Program Counter Register)
Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的。
一个内核任一时间只会执行一条线程中的指令。
每条线程都有一个独立的程序计数器,这类内存区域被称为“线程私有”的内存,目
的是为了线程切换后了能恢复到正确的执行位置。
Java方法计数器记录的是虚拟机字节码指令的地址;本地native方法值为空
Undefined
内存情况:唯一一个没有规定任何OutOfMemoryError情况的区域
Java虚拟机栈(Java Virtual Machine Stack)
线程私有,其生命周期和线程相同
方法执行时,JVM同步创建一个栈帧(Stack Frame)用与存储局部变量表,操作数
栈,动态连接,方法出口
局部变量表存放了编译期可知的各种JVM虚拟机基本数据类型,对象引用
(reference)和returnAddress(指向一条字节码指令的地址)
数据类型在其中的存储空间以局部变量槽Slot,double,long,占两个,其余占一
个。
虚拟机栈为虚拟机执行Java方法(字节码)服务
运行时常量池(Runtime Contstant Pool)
方法区的一部分,Class文件常量池表(Constant Pool Table)用于存放编译期生成
的各种字面量和符号引用,类加载后存放到方法区的运行时常量池中
动态性:既有预置入Class文件中常量池的内容,也可以在运行期间将新的常量放入
池中(String类中的intern()方法)
JAVA堆 (Java Heap)
虚拟机管理内存最大的一块
所有线程共享,虚拟机启动时创建
唯一目的存放对象实例
新生代,老年代,永久代,Eden空间,From Survivor空间,To Survivor空间
从内存分配的角度看,所有线程共享的Java堆中可以划分出许多线程私有的分配缓
冲区(Thread Local Allocation Buffer,TLAB),以提升对象分配时的效率。
本地方法栈(Native Method Stacks)
本地方法栈为虚拟机使用到本地方法服务
作用与java虚拟机栈所发挥的作用相似
方法区(Method Area)
各个线程共享的内存区域,存储JVM加载的类型信息,常量,静态变量,即时编译
器编译后的代码缓存
附:直接内存(Direct Memory)
直接内存并不是虚拟机运行时数据区的一部分。
流程:JDK1.4新加入NIO(New Input/Output)类,引入了一种基于通道
(Channel)与缓冲区(Buffer)的I/O方式,它可以直接使用Native函数库直接分
配堆外内存,通过Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作
优点:某些场景显著提高性能,避免Java堆和Native堆来回复制数据
内存情况
线程私有
程序计数器
Java虚拟机栈
本地方法栈
线程共享
Java堆
方法区
运行时常量池
内存异常
OutOfMemoryError:内存,堆,栈拓展失败
Java虚拟机栈
本地方法栈
Java堆
运行时常量池
直接内存
StackOverFlowError:栈深度超出Max允许申请
Java虚拟机栈
本地方法栈