运行时数据区域
程序计数器
一块较小的内存空间,(java中的多线程是轮流切换并分配处理器时间,在任一个确定的时刻,一个处理器只会执行一条线程。因此为了回复线程能够恢复到正确的执行位置,每条线程都有一个独立的计数器)各类线程之间计数器互不影像,独立存储,我们称这类内存区域为“线程私有”的内存。
如果正在执行的java方法,这个计数器记录的是正在执行的虚拟机指令地址;如果是Native方法,这个计数器值为空(undefined)。此区域是唯一一个在Java虚拟及规范中没有规定的OutOfMemoryError 情况的区域。
Java 虚拟机栈
java虚拟机栈,也是线程私有的(同程序计数器),他的生命周期与线程相同。
(java方法执行的内存模型)每个方法执行的时候会创建栈帧,用于存储局部变量表,操作数栈,动态链接,方法 出口信息等。
这个区域出现两种状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,扩展时无法申请到足够内存,就会抛出OutOfMerrorError异常
本地方法栈
本地方法栈(与虚拟机栈相似)。区别,虚拟机栈为虚拟机Java字节码服务。而本地方法栈则为虚拟机使用的Native服务。
本地方法区域也会抛出StackOverflowError 和 OutOfMemoryError 异常。
Java 堆
被所有线程共享的一块区域,主要存放对象的实例。随着JIT发展和逃逸分析技术成熟,也不会那么“绝对”了
java堆可以处在物理上不连续的内存空间,只要逻辑上市连续的即可,就像我们的磁盘空间一样。如果在堆中没有内存完成实例分配,并且堆也无法扩展时候,将会抛出OutOfMemoryError
方法区
方法区和Java堆一样,是线程共享的内存区域,用于存储,虚拟机加载类信息,常量,静态变量,即时编译器编译后的代码等数据。Java虚拟机规范表示方法去是堆得一个逻辑部分。但是有一个别名叫非堆。
这个区域比较难管理,内存回收主要是对常量池的回收和对类型的卸载
当方法区无法满足内存分配需求时候抛出OutOfMemoryError
运行时常量池
运行时常量池是方法区的一部分。
当常量池无法身亲到内存是也会抛出OutOfMemoryError
直接内存
不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中的内存区域。但是也被频繁使用,会出现有抛出OutOfMemoryError的现象。