JVM内部结构详解

JDK体系结构

在这里插入图片描述
javap -v/-c 可以生成JVM内部汇编语言

JVM整体结构及内存模型

在这里插入图片描述

  • 堆:new 出的对象基本存放在这里。

  • 栈:程序中每个方法都会开辟一块栈帧区域以main方法为程序入口。依次形成一个个栈帧压栈。栈中遵循FILO原则(先进后出)
    没个栈帧都有:
    - 局部变量表:方法中的局部变量
    - 操作数栈:对方法中的逻辑操作 (例如:int 变量的 增减操作)
    - 动态链接:符号引用->直接引用
    - 方法出口:记录返回main方法执行的位置

  • 方法区(元空间):常量+静态变量+类信息(初始化类的信息)

  • 程序计数器:给各个栈帧中分配程序计数器。用以记录代码执行行数。并发线程执行时 可以继续执行程序。

  • 本地方法栈:Java jar包中带native 关键字的方法。(这些方法基本都是调用C++程序)

  • 类装载子系统:类加载

  • 字节码执行引擎:
    - 修改栈帧中程序计数器的数值
    - 执行堆中 minor gc /full gc /STW(程序全部暂停命令)

堆中详细图

在这里插入图片描述
年轻代(一般占堆内存的1/3):Eden(伊甸区)
Survivor区(s0、s1)
老年代(一般占堆内存2/3)

new 的对象 初始都将放入Eden区。当Eden区满将触发字节码执行引擎执行minor gc操作
(以程序入口进入时。new 出的对象可以作为一个个的root节点。引用该节点的对象将相互串联。minor gc 将回收未引用的对象)
未被回收的对象 将从Eden区复制存到s0。该对象的代数将+1;
Eden区将清空
再次执行mimor gc后 s0中的将复制存到s1 代数再次+1;Eden 和s0一起清空。依次类推待代数为15时该对象将存进老年代。
当老年代满了后将执行Full gc 执行full gc。
执行 full gc 与 mimor gc 时都将触发 STW (Stop the World)程序将暂停运行

JVM内存参数设置

在这里插入图片描述
Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下Catalina.sh文件里):
java ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐jar microservice‐eurek
a‐server.jar

关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和-XXMaxMetaspaceSize=N
- XX:MaxMetaspaceSize: 设置元空间最大值,默认是-1,即不限制,或者说之受限于本地内存大小。
-XX:MetespaceSize: 指定元空间触发Full gc的初始阈值(元空间无固定初始大小),以字节为单位,默认是21M,达到该值就会触发full gc 进行类型卸载,同时收集器会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过-XX:MaxMetaspaceSize(如果设置了的话)的情况下,适当提高该值。这个跟早期jdk版本的 -XX:PermSize参数意思不一样,-XX:PermSize代表永久代的初始容量。
由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间进行了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始化值更大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。

          StackOverFlowError 示例:
 // JVM设置 ‐Xss128k(默认1M)
2 public class StackOverflowTest {
3
4 static int count = 0;
5
6 static void redo() {
7 count++;
8 redo();
9 }
10
11 public static void main(String[] args) {
12 try {
13 redo();
14 } catch (Throwable t) {
15 t.printStackTrace();
16 System.out.println(count);
17 }
18 }
19 }
20
21 运行结果:
22 java.lang.StackOverflowError
23 at com.tuling.jvm.StackOverflowTest.redo(StackOverflowTest.java:12)
24 at com.tuling.jvm.StackOverflowTest.redo(StackOverflowTest.java:13)
25 at com.tuling.jvm.StackOverflowTest.redo(StackOverflowTest.java:13)

结论:
-Xss设置越小count值越小,说明一个线程栈里能分配的栈帧就越少,但是对JVM整体来说能开启的线程数会更多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值