jvm内存模型/GC/jvm启动参数

本文详细解析JVM内存模型,包括堆、栈、方法区和程序计数器的职责,探讨垃圾回收(GC)机制,如ParallelGC和G1GC,并提供JVM参数设置指南。

jvm内存模型/GC/jvm启动参数

需要提前了解的知识点:

什么是jvm内存?

jvm内存是服务器内存分配给jvm独有的一块内存空间。

什么是jvm内存模型?

jvm这块独有的内存它内部是怎么划分,或者说是怎么分类的。

什么是GC?

Garbage Collection的缩写,即垃圾回收,为什么会有垃圾回收呢?因为内存空间是有限的,如果不释放一些无用的使用者,则内存将最终被使用完,所以把这些无用的使用者从内存中释放掉,即是指垃圾回收,也就是GC。

JVM内存模型

内存模型(分类)划分

  • 方法区
  • 程序计数器

从线程角度看内存模型

  • 线程间共享
    • 方法区
  • 线程间私有
    • 程序计数器

各个分类解释

    • 作用:存储对象的实例
    • 细分:
      • 新生代(1/3)
        • Eden(8/10)
        • From Survivor(1/10)
        • To Survivor(1/10)
      • 老年代(2/3)
    • 转换关系:
      • 新生代内存中的转移:新创建的对象A首先是在Eden区,经过一次MinorGc后,Eden区仍存活的对象A转移至From区,此时对象A的年龄为1。若再进行一次MinorGc,会把Eden区中仍存活的对象转移至To区,同时From区的存活对象会复制到To区,若若对象A还存在,则它此时的年龄为2。当这样不断的循环GC,当其的年龄达到15,或者Eden和Survivor都满了,则会转移至老年代中。
      • 老年代内存:会进行FullGc,把不存活的对象从内存中删掉
  • 方法区
    • 作用:存储已经被虚拟机加载的类信息、场景、静态变量、类元信息等数据
    • 细分:
      • jdk1.8之前,像字符串常量的存储内存空间称为永久代
      • jdk1.8之后,像字符串常量的存储内存空间称为MetaSpace元空间
    • 作用:记录方法调用的先后顺序及方法内的临时变量存储
    • 虚拟机栈
      • 由多个栈帧组成,每调用一个方法都是压入一个栈帧
      • 栈帧组成:局部变量、方法出口等
    • 本地方法栈
      • 调用native方法,使用的是本地方法栈,其调用的不是java自身的方法,而是调用C语言的ddl库文件,所以其有自己的内存空间,称之为本地方法栈
  • 程序计数器
    • 作用:记录代码执行到哪一行
    • 应用场景:多线程场景,当线程a挂起后,去执行线程b,当执行完线程b回到线程a需要知道从哪一行代码接着执行,所以就设计了程序计数器来记录jvm指令码对应的行数。

JVM的GC

为什么有内存GC?首先是内存空间是有限的,且内存资源是宝贵的。需要把已经不用的对象(或者是资源占用者)从内存中剔除,称之为jvm的GC。

  • 常用GC分类
    • JDK1.8默认的GC是ParallelGc = 复制算法 + 标记整理算法(串行)
    • JDK1.9默认的GC是G1Gc = 复制算法 + 标记整理算法(并行)
  • 算法分析
    • 复制算法(MiNorGc,运用在新生代)
      • 特点:其内存存储的对象存活率低
      • 逻辑:分配两块一样内存的空间A和B,把内存空间A中存活的对象Copy至内存空间B,同时清除掉内存空间A。依次反复。
      • 存在的理由:其实它是用了标记,可以理解为它是标记复制算法。因为它死亡的对象多,如果像标记整理算法那样去移动存活对象的话,效率就比较低,所以就设计了这种复制算法,只要把少量存活的Copy到另外一个内存空间,之前的内存空间直接全部释放,这样效率得以提升。
    • 标记整理算法(FullGc,运用在老年代)
      • 特点:其内存存储的对象存活率高
      • 逻辑:对内存中的死亡的对象进行标记,然后移动存活对象,释放掉边界之外的内存。
    • 其他算法
      • 标记清除算法
        • 特点:和标记整理算法一样
        • 逻辑:对内存中的死亡的对象进行标记,然后死亡对象的地址存在一个列表中,后续要新增对象就先用该死亡对象的地址。
      • 分代收集算法
        • 其实就是复制算法+标记整理算法,也就是G1Gc。

JVM参数设置及调优

  • jvm启动参数分类

    • 标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容
    • 非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容
    • 非Stable参数(-XX),此类参数各个jvm实现会有所不同,这些都是不稳定的并且不推荐在生产环境中使用。将来可能会随时取消,需要慎重使用;上都被实现),而且如果在新版本有什么改动也不会发布通知
  • 常用四大参数

    • -Xms 堆初始化值 ps.-X为非标参数,M:Memory,S:start
    • -Xmx 堆最大值 ps.X:maXimum
    • -Xmn 堆中新生代大小 ps.n:New,如不设置则为默认1:2=新:老
    • -Xss 每个线程栈大小 ps.s:stack s:size

配置原则

  1. 堆内存一般是配置服务器内存的1/4;注意一点:不能配置为全部服务器内存,因为服务器自身跑还需要内存,且jvm其他的栈、方法区、程序计数器等都需要服务器内存。
  2. Xms一般设置和Xmx一样大,避免频繁的减容扩容浪费Cpu资源;
  3. Xmn一般使用默认值,即为堆的1/3,因为新:老=1:2
  4. Xss 为每个“线程”的栈大小,如果设置多大,因为内存有限,则并发数则不会太高;如果设置太小,则方法调用的层次太深就会报栈内存溢出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值