张治峰的博客

JVM内存模型

2021-01-04

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(){
B();
}
public void B(){

}

方法出口

栈帧结束后 返回到调用它的方法的代码行号.

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线程数量

Tags: java
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章