jvm主要分三部分:堆、栈、方法区
一、栈
栈属于每个线程私有的,包含jvm栈和nativa栈和程序计数器,主要用来存储方法执行过程中需要的信息。
1、jvm栈与native栈
- jvm栈与native栈功能相同,都是用于执行方法,区别在于jvm栈用于执行java中的方法函数,而nativa栈用于执行本地方法。
- 栈是由多个栈帧组成,即每个线程调用多个方法,产生对应的栈帧,栈帧结构主要有局部变量区、操作数栈、帧数据区。
局部变量区
局部变量区用于存储方法局部变量及方法参数,取值通过索引取。
各数据类型中,double与long占两个位置,如图中double占4和5两格,则取值时取索引为4的值。
操作数栈
用于方法执行时数据的临时存储,与局部变量区不同的是它以出入栈的方式存储当前计算用到的参数。
帧数据区
方法执行过程中不可避免会引用常量池数据,帧数据区则存储这些指向常量池的地址,另外方法的异常终止、正常返回也由帧数据区处理(具体我也就了解到这了)
2、程序计数器
程序计数器用于存储下一行要执行的方法字节码地址。
二、方法区
- 方法区用于存储class的基本信息、运行时常量、静态常量等,其中运行时常量并不是固定的,程序执行过程中可由代码动态生成。这个区域是线程共享的。
三、堆
堆是jvm中占用内存最大的一块,存储代码执行过程中产生的所有对象,为了垃圾收集方便,将其分为新生代(young generation)、老年代(old generation)、持久代(perm space)。同样jvm堆也是线程共享的。
- 其中新生代是垃圾回收最主要的处理位置。
- 老年代主要存储一些大对象,大的数组等。
- 持久代则存储一些常量等不会改变的信息,这个区域不进行垃圾回收。
关于持久代
持久代存在于堆中,方法区是一个JVM规范,而持久代则是这种规范的一种实现方式(大多数虚拟机并没有实现方法区,HotSpot通过持久代实现方法区),而持久代一旦加载不会被回收,所以说持久代物理上存于堆中,逻辑上与堆区别开来两者独立。 持久代在jdk1.7开始慢慢移除,jdk1.8已经彻底移除,取而代之的是一个被称为元空间的本地内存区域。