一.JVM的内存模型及运行组成部分
内存模型
运行时组成部分
主要的组成部分为5部分: Method Area(方法区), heap(堆), VM Stack(虚拟机栈), native Method Stack(本地方法栈), Program Counter Register(程序计数器)
二.各部分解析
1.Method Area(方法区): 线程共享
a.被所有方法线程共享的一块内存区域
b.用于存储已被虚拟机加载的类信息,常量,静态变量等
c.内存回收的主要目标是常量池回收和堆类型的卸载
2.haep(堆):线程共享
a.被所有线程共享的一块内存区域(只此一块),在虚拟机启动时创建,用来存储对象实例
b.可扩展(通过设置JVM参数-Xms 跟 -Xmx 实现大小)
c.当堆没有内存可以分配给实例,也无法扩展时,抛出OOM(OutOfMemoryError)
d.主要存储对象本身,数组。
3.VM stack(虚拟机栈): 线程私有
a.每个方法在运行时创建一个栈帧,用来存储局部变量,操作数,动态链接,方法返回地址
b.每个方法运行到结束,对应一个栈帧在栈中的入栈和出栈
c.一般情况下,栈指虚拟机栈中的局部变量部分
d.局部变量在编译时分配:
如果线程请求的栈深度大于虚拟机栈的深度,则会抛出StackOverflowError(栈溢出)
如果虚拟机栈可以进行动态扩展,但仍然无法满足内存需要,则抛出OOM
4.Native Method Stack(本地方法栈) 线程私有
与vm stack 作用和原理非常相似。区别只不过是虚拟机栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的
5.Program Counter Register(程序计数器):线程私有
a.jvm中线程通过轮流的方式切换来获取cpu执行时间,每个cpu内核在同一个时间只会执行一条指令,为了能够使线程回复到切换前的执行位置,所以每个线程都有自己的程序计数器,并且互不干扰。
b.因为程序计数器的使占的数据空间大小固定,所以程序计数器不会发生oom。