运行时数据区

1、线程私有
1.1、程序计数器
1、占用一块较小的内存空间
2、当前线程所执行的字节码行号指示器
3、字节码解释器工作时通过改变计数器值来选取下一条需要执行的字节码指令
4、它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等都依赖它
5、执行Java方法,值为字节码指令地址
6、执行Native方法,值为空 Undefined
1.2、Java虚拟机栈
调整大小参数(-Xss)
1、生命周期和线程相同
2、每个方法被执行时,Java虚拟机会同步创建一个栈帧用于存放局部变量表、操作数栈,动态链接,方法出口等信息
局部变量表
存放基本数据类型和对象引用,其中64位的long和double占两个连续变量槽,其余数据类型占一个变量槽
大小:编译期间完成确认,大小指变量槽数量,最大容量存放在Class方法表的code属性max_locals项中
使用:Java虚拟机通过索引定位方式使用局部变量表
单位:已变量槽为最小单位,变量槽大小以虚拟机实现为准
变量槽:可以重用
操作数栈
大小:存放在Class方发表的code属性max_stacks项中
使用:后入先出
Java虚拟机的解释执行引擎被称为“基于栈的执行引擎”,里面的“栈”就是操作数栈
例子:1+2=3,1和2先后入栈,字节码指令iadd取出2和1相加,结果在入栈
动态链接
字节码中方法调用指令都是以符号引用表示。类加载阶段或第一次使用的时候符号引用转化直接引用,称为“静态解析”;每一次运行期间符号引用转化直接引用,称为“动态链接”
方法返回地址
遇到返回字节码指令(正常调用完成)
遇到本方法的异常表中没有匹配的异常处理器,就会导致方法退出(异常调用完成)
1.3、本地方法栈
本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务
2、所有线程共享
2.1、方法区
1、别名:非堆(Non-Heap)
2、存储已被虚拟机加载的类型信息,常量,静态变量、即时编译器编译后的代码缓存等数据
jdk8以前使用【永久代】实现方法区
调整大小参数(-XX:PermSize 和 -XX:MaxPermSize)
jdk8及以后使用【元空间】实现方法区
元空间直接使用本地内存,内存大小受物理机限制
jdk7及以后把【常量,静态变量移至Java堆中】
元空间参数 |
描述 |
|---|---|
| -XX:MetaspaceSize | 初始化的Metaspace大小,控制元空间发生GC的阈值。GC后,动态增加或降低MetaspaceSize。在默认情况下,这个值大小根据不同的平台在12M到20M浮动。使用Java -XX:+PrintFlagsInitial命令查看本机的初始化参数 |
| -XX:MaxMetaspaceSize | 限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。在本机上该参数的默认值为4294967295B(大约4096MB) |
| -XX:MinMetaspaceFreeRatio | 当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数(即实际非空闲占比过大,内存不够用),那么虚拟机将增长Metaspace的大小。默认值为40,也就是40%。设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存 |
| -XX:MaxMetasaceFreeRatio | 当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。默认值为70,也就是70% |
| -XX:MaxMetaspaceExpansion | Metaspace增长时的最大幅度。在本机上该参数的默认值为5452592B(大约为5MB) |
| -XX:MinMetaspaceExpansion | Metaspace增长时的最小幅度。在本机上该参数的默认值为340784B(大约330KB为) |
2.2、Java堆
调整大小参数(-Xms 和 -Xmx)
1、虚拟机启动时创建
2、主要用来存放对象的实例
3、分为新生代(Eden,From Survivor,To Survivor 默认比率为8:1:1),老年代
3.1、新生代采用标记-复制算法,收集器工作时把Eden,From Survivor对象复制到To Survivor中,当To Survivor不够时采用分配担保模式,多余对象存入老年代
3.2、老年代采用标记-清除算法,当内存碎片达到临界值时就会采用标记-整理算法整理一次内存
3、运行时常量池
1、运行时常量池是方法区的一部分
2、用于存储字面量、符号引用、符号引用翻译过来的直接引用
3、jdk8及以后再元空间实现
4、直接内存
1、受制于本机总内存大小以及处理器寻址空间的限制
2、内存分配不受Java堆大小限制
3、基于通道和缓冲区会用到,内存引用标识在Java堆 DirectByteBuffer 中

浙公网安备 33010602011771号