JVM内存模型以及参数设置(一)

1、jvm内存模型

在这里插入图片描述
JVM运行时内存主要有五个部分,分别是堆、栈(线程)、方法区、本地方法栈以及程序计数器。
当程序运行一个线程时,其中的栈、本地方法栈和程序计数器是线程私有。换句话说,就是每一个线程都有一个自己的栈、本地方法栈和程序计数器,堆和方法区则是线程共享。
下面以当程序运行一个user类或math类为例,当调用程序调用main方法时,生成一个线程1。
jvm给这个线程分配了栈、本地方法栈和程序计数器。
1)本地方法栈:这里主要存放的是一些native方法。
2):线程1调用的到的每个方法都会在栈中分配一个栈帧。例如main方法调用了compute()方法,栈给该方法分配了一个栈帧,里面主要包含四个部分:局部变量表、操作数栈、动态链接和方法出口。局部变量表和操作数栈涉及到jvm的指令,这四个部分的作用这里不做详细讲述。
3)程序计数器:这个部分简单来说就是存储了这个线程1代码运行的步骤。
4):堆空间是共享的,主要存放的就是一些对象实例,以及指向这些对象实例的指针。比如我new Uesr()了一个类,那这个类new的对象就存在堆内存中。
5)方法区:这里在jdk8之前被称为永久代,之后被称为元空间。这里存放的是一些运行时常量池、静态变量和类信息。

2、GC

GC一般来说分为minor gcfull gc
1)minor gc
堆空间从整体上说分为年轻代和年老代。年轻代占了三分之一,年老代占了三分之二。
年轻代分为Eden区和survivor区,其中Eden区占据了年轻代十分之八大小,survivor区则占据了十分之二。
其中survivor区又分为s0和s1两个区,各占据二分之一大小。
下面来说一下minor gc的具体过程。
1、新生成的对象首先会存放在年轻代的Eden区中,当Eden区空间满了之后,就需要进行第一次gc,这个时候会根据gc root(就是还在使用的对象链条上的所有数据),判断哪些对象已经不用了,就会将改对象回收。剩下还存活的对象,会放入到s0这个区中,同时将改对象的标记为1.
2、第一次minor gc过后,如果Eden区的空间又满了,这个时候就需要进行第二次gc,将Eden区和s0区中还存活的对象放入s1中,同时也会给对象添加一个标记2(对象每存活一次就会添加一个标记,默认从1-15)
3、第三次gc,又会将Eden区和s1区存活的对象放入到s0中。。
4、循环往复,如果有的对象身上的标记到了15,那么下一次就会将这个对象放入到年老代中。这就是minor gc。
2)full gc (又叫major gc,但是major gc通常发生在年老代。)
full gc没有官方定义,通常是回收整个堆的内存,包含年轻代、年老代、元空间等。
注意:在进行full gc 的过程中,会出现STW状态(当然在其他gc也会出现,区别在于时间长短),即在这次GC的全过程中所有⽤户线程都是处于暂停的状态。这回导致程序的卡顿,因此应尽量避免出现SWT状态。

3、jvm参数设置(下篇文章会更加深入介绍)

在这里插入图片描述
-XX:MaxMetaspaceSize:方法区空间最大值,默认是不设置
-XX:MetaspaceSize:元空间初始大小(这个值建议设置大一点,因为初始值21m),举个例子,项目war包启动时有时候时间会比较长,一部分原因是元空间初始值设置太小,经常进行full gc

总结

本文简要介绍了jvm的内存模型和垃圾回收机制。下文将会在jvm内存模型的基础上深入剖析jvm的内存分配机制,并探究如何最佳分配jvm的内存参数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值