Java内存区域与内存溢出异常
java虚拟机管理的的运行时数据区域
- 程序计数器
- 小内存区域,可看作当前线程所执行的字节码的行号指示器,字节码解释器就是依赖于它工作,通过改变它的值,直接骂解释器能获取到要执行的指令
- 每一个线程都会有一个独立的程序计数器(为了线程切换后能恢复到正确的位置),会独立存储,这种内存被称为“线程私有‘的内存
- 需要注意的是,如果线程正在执行的是Java方法,则这个计数器记录的是正在执行的虚拟机字节码指令的地址,但是如果是Native方法,则计数器值为空
- 此内存区域没有任何的OOM
- Java虚拟机栈
- 线程私有的,生命周期和线程相同
- 描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用来存储局部变量表、操作数栈、动态链接、方法出口等信息,每个方法从调用到完成的就对应一个栈帧在虚拟机栈中入栈到出栈的过程
- 现在一般所指的栈是虚拟机栈中局部变量表的部分,里面存放了编译期可知的各种基本数据类型、对象引用(只有64位的long和double类型的数据会占用2个局部变量空间,其余为一个),在方法运行运行期间,不会改变局部变量表的大小
- 在这个区域有两种异常情况。(1)StackverfloError异常:线程请求的栈深度大于虚拟机允许的深度 (2)OOM:进行扩展时无法申请到足够的内存
- 本地方法栈
- 为虚拟机使用到的Native方法服务
- 抛出的异常与虚拟机栈相同
- Java堆
- 被所有线程共享的区域,在虚拟机启动时创建,用于存放对象示例(但并非所有的对象都分配在堆上)
- 这个区域是垃圾收集器管理的主要区域,采用分代收集算法的话,java堆还可以分为:新生代和老年代