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)
- 新生代(1/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。
- 标记清除算法
- 复制算法(MiNorGc,运用在新生代)
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/4;注意一点:不能配置为全部服务器内存,因为服务器自身跑还需要内存,且jvm其他的栈、方法区、程序计数器等都需要服务器内存。
- Xms一般设置和Xmx一样大,避免频繁的减容扩容浪费Cpu资源;
- Xmn一般使用默认值,即为堆的1/3,因为新:老=1:2
- Xss 为每个“线程”的栈大小,如果设置多大,因为内存有限,则并发数则不会太高;如果设置太小,则方法调用的层次太深就会报栈内存溢出。
本文详细解析JVM内存模型,包括堆、栈、方法区和程序计数器的职责,探讨垃圾回收(GC)机制,如ParallelGC和G1GC,并提供JVM参数设置指南。

36

被折叠的 条评论
为什么被折叠?



