JVM之内存模型
作者:互联网
内存模型
虚拟机栈
每一个线程开启执行方法的时候都会在虚拟机栈中开辟一块内存空间,每一个线程内方法调用的时候都会开启一块栈帧内内存空间,每一个方法的调用和结束都会伴随着入栈和出栈的过程,一个线程不会同时操作它的多个栈帧,只会执行栈顶的方法。
局部变量表
变量值的存储空间,主要存储的是方法参数和局部变量,虚拟机通过索引定位的方式使用。
操作数栈
是一个后入先出栈,是在算数运算或调用其他方法的时候进行参数传递的一块内存空间。在概念模型中,栈帧是独立的,但是通常情况下,操作数栈和局部变量表的一部分是重叠的,因为这样可以减少相同参数复制传递。
动态连接
每一个栈帧中都包含一个指向运行时常量池中该栈帧所属方法的引用。所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。动态链接的作用是为了将这些符号引用转换为调用方法的直接引用。
方法返回地址
方法的返回分为两种情况,一种是正常退出,退出后会根据方法的定义来决定是否要传返回值给上层的调用者,一种是异常导致的方法结束,这种情况是不会传返回值给上层的调用方法.不过无论是那种方式的方法结束,在退出当前方法时都会跳转到当前方法被调用的位置,如果方法是正常退出的,则调用者的PC计数器的值就可以作为返回地址,如果是因为异常退出的,则是需要通过异常处理表来确定.在方法的的一次调用就对应着栈帧在虚拟机栈中的一次入栈出栈操作,因此方法退出时可能做的事情包括,恢复上层方法的局部变量表以及操作数栈,如果有返回值的话,就把返回值压入到调用者栈帧的操作数栈中,还会把PC计数器的值调整为方法调用入口的下一条指令。
程序计数器
每一个线程独有的一块小的内存空间,执行速度非常快,存储当前线程正在或者将要执行指令的在方法区中的地址。控制程序执行的分支,循环异常等操作都需要依赖程序计数器。多线程的场景下,CPU通过时间片轮转来进行线程的上下文切换,当线程等待再执行的时候就需要知道上一次执行时的位置,所以程序计数器是线程私有的。
方法区(元空间)
主要存放,常量,静态变量,类信息。如果静态变量存储的是对象实例,那么方法区中存储的就是对象实例在堆中的内存地址。栈帧中的局部变量也是如此。
本地方法栈
保存native方法进入区域的地址的一块内存空间。
堆
老年代占整个内存的三分之二,s1 s0 占剩下的十分之一。创建对象的时候首先会向Eden space中添加,当已满不能再添加时候进行ManorGC,然后通过可达性算法来标记对象是否非被引用,然后进行回收,标记过的就会增加年龄(对象头中设置),进入下一个分代区,当年龄增加到15时会提升到老年区,每一个分区都会进行GC。
标签:调用,模型,局部变量,内存空间,线程,内存,JVM,方法,栈帧 来源: https://blog.csdn.net/weixin_44052985/article/details/120919603