深入理解JVM

一、JVM整体结构及内存模型

在这里插入图片描述
JVM虚拟机主要由以下部分组成:

  1. 栈(线程):存放线程的局部变量,特点:先进后出(FILO),先执行完子方法再执行完主线程
  2. 栈帧:存放线程中方法的局部变量、操作数栈、动态链接和方法出口。
    a. 局部变量:方法中的变量
    b. 操作数栈:临时保存对变量进行操作后的值,例如:临时保存2*3的值6
    c. 动态链接:保存方法的地址
    d. 方法出口:保存原入口执行位置,用于继续执行原方法剩余代码,定位原方法执行位置
  3. 程序计数器:记录存放执行代码的位置
  4. 堆:存放对象的区域
  5. 方法区(元空间):类存放地址(常量、静态变量和类信息)。使用的是物理内存。
  6. 本地方法栈:存储C语言写的方法的一个栈

通过分析JVM的各个组成部分可以看出其中占用内存最大的就是堆,堆作为存储对象的空间,咱们再深入了解堆的结构

二、堆的内存模型

在这里插入图片描述
堆内存主要由以下部分组成:

  1. Eden区:对象主要存放位置,
  2. survivor区(s0/s1):当执行yong gc时,存储新生代里面的非垃圾对象
  3. 年轻代:eden+survivor
  4. 老年代:存放多次yong gc后还存在的对象,大对象也存放在这里

JVM默认情况下,堆内存分配比例:
年轻代/老年代=1:2
Eden:s0:s1 = 8:1:1

例如:分配给堆内存工1G,则分配情况如下

老年代占2/3*1G 
年轻代占1/3*1G 
Eden占1/3*8/10*1G
s0占1/3*1/10*1G
s1占1/3*1/10*1G

GC原因理解

GC的主要原因:堆内存满了。当进行GC时,JVM会进入STW状态(stop the world),此时JVM是无法处理业务的。
GC分为两种:Young GC和Full GC

Young GC出现原因

在不断创建对象的过程中,当Eden区域被占满,此时会开始做Young GC也叫Minor GC,执行GC流程如下:
1) 对Eden区域和S0/S1区域的对象进行扫描,找出可销毁的对象
2)将Eden区域经过GC不能被回收的对象存储到To S0/S1 区域(轮流存储)。大对象和存活很久的对象会被存储到老年代

Full GC出现原因

当老年代区域被占满时就会开始执行Full GC,Full GC是一个长耗时操作应尽量避免。此时若仍无法回收到足够的空间则会出现OOM(out of memory)。

JVM内存参数设置/优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值