JVM 运行时内存区域
JVM 运行时数据区主要分为: 堆、虚拟机栈、本地方法栈、程序计数器、方法区 五大区域,具体作用如下图所示:
虚拟机栈
虚拟机栈由一个个栈帧(一个方法调用就会产生一个栈帧,方法结束栈帧就销毁)组成,而栈帧由 局部变量表、操作数栈、动态链接、方法出口等组成。
局部变量表
这块区域存储方法中的局部变量和方法参数,比如 int a = 1;这行代码中 a= 1 就存在其中。变量用卡槽的方式进行存储,一个卡槽4个字节,每个变量至少占用一个卡槽,对于long,double类型则会占用两个卡槽,
非静态方法调用,它第一和卡槽存储的是this指针。
操作数栈(FILO)
这块区域对局部变量表的数据及临时数据进行计算以及保存结果使用,如下代码;
public void test(){
int a = 1;
int b = 2;
int c = a+b;
}
a,b两个变量是放在局部变量表中的,计算 a+b 时 ,先将局部变量 a 和 b 的值放入操作数栈中,然后取出来做 加 操作 ,得出结果3 入栈,在3保存到局部变量表中的变量c当中。
动态链接
在执行A方法时会生成一个栈帧,A方法会调用B方法,动态链接就是找到B方法的入口。(动态链接持有当前类的常量池的引用,通过符号引用转为直接引用)。白话就是找到执行B方法的入口(B方法的内存地址)
public void A(){ |
方法出口
栈帧结束后 返回到调用它的方法的代码行号.
JVM 内存参数
参数 | 说明 | 示例 |
---|---|---|
-Xss | 虚拟机栈大小 | ‐Xss512k |
-Xms | 堆的初始大小 | -Xms1024m |
-Xmx | 堆可到达的最大值 | -Xms20484m |
-Xmn | 堆中新生代的大小 | -‐Xmn1024M |
-XX:MaxMetaspaceSize | 元空间最大值, 默认是-1,即不限制或者,只受限于本地内存大小 | ‐XX:MaxMetaspaceSize=256M |
-XX:MetaspaceSize | 元空间触发Fullgc的初始阈值,单位为字节, 默认21M | ‐XX:MetaspaceSize=256M |
元空间触发fullgc 后,jvm会对元空间触发full gc的阈值进行调整,如果释放了大量空间会降低值,释放空间少的话就会加大改值(最大不超过MaxMetaspaceSize设置的值)
通常在项目启动时发生大量FULL GC时都是由元空间或者永久代发生大小调整导致的,这个时候建议将MaxMetaspaceSize 和 MetaspaceSize设置成一样并比初始值大。8G内存推荐设置256M
常见问题
为什么设置的栈内存越小 栈帧的数量相对也会更小,但是对JVM来说线程数会更多?
简单来说就一个公式: 所有栈可用内存 = 单个栈内存x线程数量
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章