



实际上栈帧你可以把认为它把不同方法内存局部变量的一些内存给它隔离开来



一、运行时数据区(内存模型)
这是JVM在运行时划分的内存区域,包含4个核心部分:
-
堆
- 是Java对象存储的主要区域,通过
-Xms(初始堆大小)、-Xmx(最大堆大小)配置。 - 堆内部又分为新生代 ,通过
-Xmn配置其大小。
- 是Java对象存储的主要区域,通过
-
方法区
- 存储类信息、常量、静态变量等,JDK8及以后用"元空间"实现,通过
-XX:MetaspaceSize(元空间初始阈值)、-XX:MaxMetaspaceSize(元空间最大值)配置。
- 存储类信息、常量、静态变量等,JDK8及以后用"元空间"实现,通过
-
栈(线程私有)
- 每个线程对应一个栈,存储方法调用的局部变量、方法出口等,通过
-Xss配置单个线程栈的大小。
- 每个线程对应一个栈,存储方法调用的局部变量、方法出口等,通过
二、JVM参数配置(以Spring Boot+Tomcat为例)
图片给出了Spring Boot程序的JVM参数示例:
java -Xms248M -Xmx248M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar
其中元空间参数是重点说明的内容:
-XX:MaxMetaspaceSize:设置元空间的最大值,默认-1(不限制,仅受物理内存约束)。-XX:MetaspaceSize:元空间触发Full GC的初始阈值(默认21M)。当元空间占用达到这个值时,会触发Full GC并调整该阈值(释放空间多则降低,释放少则在不超过MaxMetaspaceSize的前提下提高)。
三、元空间参数的优化建议
由于元空间大小调整需要触发Full GC(开销很大) ,所以建议:
将MetaspaceSize和MaxMetaspaceSize设置为相同的值 ,且比初始值大(比如8G物理内存的机器,建议都设为256M)。
这样可以避免元空间动态调整导致的频繁Full GC,提升程序启动/运行的稳定性。


这两张图是围绕高并发订单系统的JVM内存调优展开的,核心是通过合理配置内存区域,减少Full GC(避免影响系统性能),下面分图解释:
第一张图:高并发订单系统的内存压力分析
这张图展示了日均50万订单系统的流量特征+内存消耗逻辑,最终给出了对应的JVM参数配置:
-
流量&订单特征
- 亿级点击→日均5000万用户→10%支付转化率→日均50万订单;
- 大促时每秒1000单(是日常的几十倍),订单系统拆分为多实例(3核4G/4核8G)承载。
-
内存消耗计算
- 单个订单对象≈1KB → 大促每秒1000单≈1MB/秒;
- 但订单涉及库存、优惠券等对象,内存放大20倍→20MB/秒;
- 再加异步操作(如订单状态同步),内存再放大10倍→200MB/秒。
-
对应的JVM参数
bashjava -Xms3072M -Xmx3072M -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M -jar xxx.jar(堆设为3G,元空间固定512M,避免动态调整)
第二张图:JVM调优目标------减少Full GC
这张图是阿里面试题的调优思路,核心是"让对象尽量在新生代回收,少进老年代":
-
内存区域配置
- 堆总大小3G(
-Xms/-Xmx=3072M),其中新生代2048M (-Xmn=2048M,包含Eden区800M、S0/S1各100M),老年代2G; - 线程栈1M(
-Xss=1M),元空间256M(固定大小)。
- 堆总大小3G(
-
调优逻辑
- 线程每秒产生60MB对象,新生代Eden区800M→约14秒填满Eden,触发Minor GC(新生代GC,停顿短);
- 让大部分对象在Minor GC时被回收,少进入老年代→老年代不会频繁填满,从而避免Full GC(老年代GC,停顿长)。
-
核心结论
JVM调优的关键是:让对象尽量在新生代分配/回收,减少老年代占用,同时给足内存,避免新生代频繁GC。

