运行时数据区
方法区
作用:存储已被虚拟机加载的类信息,常量,静态变量,即使编译器编译后的代码
线程共享
抛出OutofMemoryError
注:
1.Hotspot上称其为永久代(Permanent Generation)
2.物理上不需要连续
3.可选择固定大小或可扩展
4.运行时常量池是方法区的一部分
虚拟机栈
作用:每创建一个线程,虚拟机创建一个虚拟机栈
存储:栈帧
线程私有
抛出:StackOverflowError和OutofMemoryError
注:
1.生命周期与线程相同
2.每个方法执行时会创建一个栈帧
本地方法栈
作用:为虚拟机执行Native方法服务
线程私有
抛出:StackOverflowError和OutofMemoryError
注:
- 使用方式虚拟机规范未强制规定
堆
作用:存放对象实例
线程共享
无法扩展时会抛出OutofMemoryError
注:
1.可以处在物理上不连续的空间
程序计数器
定义 : 是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
线程私有
注:
1.如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址
2.如果正在执行的是Native方法,这个计数器的值为空(Undefined)
3.次内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域
(栈帧:
存储
1.局部变量表(基本数据类型,对象引用,returnAddress) 2.操作数栈 3.动态链接 4.方法出口信息
方法调用 —> 栈帧入栈
方法完成 —> 栈帧出栈
线程共享:方法区,堆
线程私有:本地方法区,虚拟机栈,程序计数器
StackOverflowError和OutofMemoryError的区别
- StackOverflowError:当线程请求的内存大小大于所配置的初始化大小,将抛出StackOverflowError。比如配置大小为128M,而栈里的内存分配超过了这个大小,通常发生在方法递归调用深度过大时候。
- OutOfMemoryError:如果JVM内存大小是可扩展的,当然一般都是可以扩展的,当自动扩展到计算机本身内存大小时会抛出OutOfMemoryError。比如内存为2G,当JVM超过配置大小自动扩展至2G时会抛出OutOfMemoryError。