Java运行时内存分配
Java是多线程的,CPU可以在多个线程执行中分配执行时间片段
1.程序计数器
程序计数器是虚拟机中一块较小的内存空间,主要用于记录当前线程执行的位置
当某一个线程被CPU挂起时,需要记录代码已经执行到的位置,方便CPU重新执行此线程时,知道从哪行指令开始执行
ps: 1.在Java虚拟机规范中,对程序计数器这一区域没有规定任何OutOfMemoryError情况
2.程序计数器是线程私有的,每条线程内部都有一个私有程序计数器,它的生命周期随着线程的创建而创建,随着线程结束而结束
3.当一个线程正在执行一个Java方法的时候,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是Native方法,这个计数器值则为空(Undefined)
2.虚拟机栈
虚拟机栈是线程私有的,与线程的生命周期同步
在Java虚拟机规范中,对这个区域规定了两种异常状况:
StackOverflowError:当线程请求栈深度超出虚拟机栈所允许的深度时抛出
OutofMemoryError:当Java虚拟机动态扩展到无法申请足够内存时抛出
JVM是基于栈(虚拟机栈)的解释器执行的,DVM是基于寄存器解释器执行的
虚拟机栈的初衷是用来描述Java方法执行的内存模型
每个方法被执行的时候,JVM都会在虚拟机栈中创建一个栈帧
栈帧
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构
每一个线程在执行某个方法时,都会为这个方法创建一个栈帧
一个线程包含多个栈帧,而每个栈帧内部包含:局部变量表、操作数栈、动态连接、返回地址
Java堆(Heap)
是Java所管理的内存中最大的一块,该区域唯一目的就是存放对象实例
是Java垃圾收集器(GC)管理的主要区域,有时候也叫做"GC堆"
是所有线程共享的内存区域,被分配在此区域的对象如果被多个线程访问,需要考虑线程安全问题
按照对象存储时间的不同,队中的内存可以划分为:新生代和老年代
方法区
方法区是JVM规范里规定的一块运行时数据区
方法区主要是存储:
已经被JVM加载的类信息(版本、字段、方法、接口)、常量、静态常量、即时编译器编译后的代码、数据
该区域是被各个线程共享的内存区域