JVM 相关知识点总结

JVM相关知识点很多,总结了一部分,全是干货。

JVM内部存储

JVM内存区域分为虚拟机栈、本地方法栈、堆、方法区、程序计数器

虚拟机栈

局部变量、基本数据类型、对象引用、和字节码指令地址 、为java方法服务

本地方法栈

为本地方法服务

堆(主要探讨)

内存

方法区

类、常量、静态变量,线程内存

程序计数器

线程位置的计数器

 

内存分配机制

 

内存分配主要指堆中的内存分配,也是GC主要区域

堆 (-Xms -Xmx)(Java Heap) 以分代法为基础,将内存分为:

 

新生代(Young generation -Xmn): 新生对象放在年轻代里,尽可能快速收集生命周期短的对象

分为三个区:Eden、两个Survivor。Eden满了给 Survivor,Survivor满了会把从另一个Survivor复制过来的且存活的对象 复制到年老区(该过程为一次Minor GC, 单纯Survivor 满不会引发 Minor GC)。两个Survivor区是对称的,可能同时有Eden 获取的对象。而年老区的对象都是只有从第一个Survivor取过来的,Survivor区总有一个是空的。Survivor可以配置多个,这样可增加新生代,减少沦为OG的可能性

老年代(OG -XX):经历N次垃圾回收仍然存活的对象。OG存的都是生命周期比较长的对象。

持久代(JDK1.8后移除,转为元空间):存放静态文件,对GC没有显著影响,可能会动态生成或调用class。因为其使用堆外内存,也就是直接内存,元空间的最大可分配空间就是系统可用内存空间可以避免永久代的内存溢出问题

 

Minor GC : 对象在 Survivor 区中每熬过一次 Minor GC,Age增加一岁,当达到阈值时 GC可转为老年代 (该阈值 : -XX:MaxTenuringThreshold)

Full GC:当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代,

               当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载

 

参数调优

 

JVM参数调优主要针对减少FullGC次数和对持续时间的优化。

引入系统吞吐量概念(进程可用时间/运行总时间)

进程可用时间是指进程运行总时间减去安全点暂停时间。

FullGC是安全点暂停时间较长的主要原因:

堆内存YG:OG=1:2当局部变量远远大于全局变量时,局部变量生命周期都很短。需重新配置

-Xmx:-Xms -XMx 设置初始/最大堆大小。xmx越大。持续时间越长。xmx越小,FullGC次数越多

YG优化:小对象避免发往OG,------合理设置晋升年龄范围。

默认Eden:s1:s2 = 8:1:1 年轻一点MinorGC较老一代 MinorGC更频繁,但是速度较快,所以 短寿命的尽量留在GC收回。若s比较太小可能导致对象直接晋升OG。可以设置SurvivorRatio ,对象达到S区一半时,晋升年龄更大。 大对象直接放给OG,设置PretenurSizeThreshold = 1024,超过1k对象直接OG

OG优化:

OG默认使用Parallel-old垃圾收集器,采用标记清除算法,安全天暂停线程,然后多线程并行GC 会造成时许时间过长。通常启用CMS收集器代替。(特点:GC线程与用户线程同步进行)

 

总结优化阈值:

1. YG中 Age 计数参数 MaxTenuringThreshold :控制新生代需要经历多少次GC晋升到老年代中的最大阈值

2. 对象大小参数 PretenurSizeThreshold  : 超过1k对象直接OG

3. survivor 大小参数 :SurvivorRatio :

4. survivor 个数: Survivor可以配置多个,这样可增加新生代,减少沦为OG的可能性

GC机制

GC有两种:并行、串行

GC机制是由JVM一个被称为垃圾回收器的守护线程执行,用来清理需要清除的对象,回收堆内存。

在从内存回收一个对象之前会调用对象的finalize()方法。

当一个对象通过一系列根对象都不可达时就会被回收。(简而言之,当一个对象的所有引用都为null。循环依赖不算做引用,如果对象A有一个指向对象B的引用,对象B也有一个指向对象A的引用,除此之外,它们没有其他引用,那么对象A和对象B都、需要被回收)

 

GC 算法

 

 

1.引用计数法

解释:增加一个变量引用,引用计数器加一。减少一个引用,计数器减一。 当计数器为0时,GC回收

缺点:频繁加减法 会增加对系统资源的消耗

内存泄露:无法处理循环引用的情况。假设两个对象 A和B,A引用了B对象,并且B中也引用了A对象,

那么这时两个对象的引用计数器都不为0,但是由于存在相互引用导致无法垃圾回收A和 B,导致内存泄漏。

2.标记清除法

解释:标记阶段、清除阶段。标记阶段标记所有可达对象,清除未标记对象

缺点:垃圾回收后可能存在大量内存碎片。因为对象所占地址空间是固定的

3.标记压缩清除法

解释:标记、压缩、清除。标记后的对象放在一起,确定开始和结束地址。集体清除不会有遗留的内存碎片。

缺点:压缩阶段占用系统消耗。标记过多,效率会下降

4.复制算法(新生代)

解释:将内存分为两块,使用其中一块。垃圾回收时将该块中存活的对象复制到另一块未使用的内存中。清除使用的内存块的所有对象。未使用内存块激活为使用内存块。使用内存块转为未使用内存块。

缺点:存货对象较多时,效率比较差。并且空间折半,内存资源浪费

优点:不会产生内存碎片

5.分代法(Java堆)

解释:根据对象生命周期长短将其分块。再根据每块内存特点,使用不同回收算法,提高回收效率

因此。java虚拟机中的堆根据这种算法分为新生代(复制)和老年代(标记压缩清除)

6.分区算法

解释:将整个空间划分为连续不同的小区间,每个区间独立使用。独立回收

优点:可以一次回收多个小区间。

回收配置

Java提供多种类型的垃圾回收器。JVM中的垃圾收集一般都采用“分代收集”,不同的堆内存区域采用不同的收集算法,主要目的就是为了增加吞吐量或降低停顿时间。

Serial收集器:新生代收集器,使用复制算法,使用一个线程进行GC,串行,其它工作线程暂停。

ParNew收集器:新生代收集器,使用复制算法,Serial收集器的多线程版,用多个线程进行GC,并行,其它工作线程暂停。使用-XX:+UseParNewGC开关来控制使用ParNew+Serial Old收集器组合收集内存;使用-XX:ParallelGCThreads来设置执行内存回收的线程数。

Parallel Scavenge 收集器:吞吐量优先的垃圾回收器,作用在新生代,使用复制算法,关注CPU吞吐量,即运行用户代码的时间/总时间。使用-XX:+UseParallelGC开关控制使用Parallel Scavenge+Serial Old收集器组合回收垃圾。

Serial Old收集器:老年代收集器,单线程收集器,串行,使用标记整理算法,使用单线程进行GC,其它工作线程暂停。

Parallel Old收集器:吞吐量优先的垃圾回收器,作用在老年代,多线程,并行,多线程机制与Parallel Scavenge差不错,使用标记整理算法,在Parallel Old执行时,仍然需要暂停其它线程。

CMS(Concurrent Mark Sweep)收集器:老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记清除算法,多线程,优点是并发收集(用户线程可以和GC线程同时工作),停顿小。

使用-XX:+UseConcMarkSweepGC进行ParNew+CMS+Serial Old进行内存回收,优先使用ParNew+CMS(原因见Full GC和并发垃圾回收一节),当用户线程内存不足时,采用备用方案Serial Old收集。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值