JVM优质博客内容及知识点汇总

在这里插入图片描述

在这里插入图片描述
JVM参数调优
https://zhuanlan.zhihu.com/p/58897189
https://www.cnblogs.com/anyehome/p/9071619.html
JVM类加载器机制与类加载过程(运行main方法的原理)
https://blog.csdn.net/m0_45406092/article/details/108976907
《Java虚拟机原理图解》1.3、class文件中的访问标志、类索引、父类索引、接口索引集合
https://blog.csdn.net/luanlouis/article/details/41039269
java对象在内存中的结构(HotSpot虚拟机)
https://www.cnblogs.com/duanxz/p/4967042.html

Class文件划分七个区域,通过区域间的关联完成了对整个类的描述,会有固定的地方对字段、方法、类名、父类名、实现的接口等进行描述,但是很多描述可能存储的是类似索引的指针,例如指向常量池中,常量池和访问标志中存储一些具体信息。属性表集合和访问标志可能也储存了一些具体信息。

Class文件由七个部分组成:
魔数与Class文件版本
常量池
访问标志
类索引、父类索引、接口索引
字段表集合
方法表集合
属性表集合

魔数与Class文件版本:用于判断文件是否是能被jvm接收的class文件,固定值是0xCAFEBABE(咖啡宝贝)
常量池: 用于存放类中定义的常量变量、全限定类名全限定方法名
访问标志:用于记录class文件中元素的类型,例如记录是否是public 是否是final 是不是一个接口 是否是注解、枚举、abstract等
类索引、父类索引、接口索引:类索引指向常量池中的一个常量池项,记录了这个类的全限定类名。父类索引同理,接口索引是个集合记录了该类实现的多个接口同样指向多个记录了全限定类名的常量池项
字段表集合
用于对类中的变量(局部变量除外)等字段进行描述,存储了访问标志、作用域是否静态可变可见性数据类型等信息
方法表集合
用于对类中的方法,进行描述,存储了作用域、返回值类型是否静态等
属性表集合
在Class文件、字段表和方法表都可以携带自己的属性信息,这个信息用属性表进行描述,用于描述某些场景专有的信息。

Java中可以作为GC Roots的对象

虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(即一般说的native方法)中引用的对象

finalize:
如果对象重写了finalize方法,在第一次垃圾回收的时候会调用该方法,GC看到对象重写了该方法会将其丢到一个队列中,由finalizeThread对其进项finalize方法的调用

垃圾回收策略和算法,看这一篇就够了!
https://zhuanlan.zhihu.com/p/172515098
java中内存泄露8种情况的总结
https://blog.csdn.net/weter_drop/article/details/89387564

JDK8的默认垃圾收集器 Parallel 收集器 也叫吞吐量收集器。主要关注收集器的吞吐量属性

吞吐量是指。用户线程执行时间比例。吞吐量越大越好
暂停时间也就是stoptheworld。暂停时间越短越好

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。基于“标记-清除”算法实现,它的运作过程如下:
1)初始标记
初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快
2)并发标记
进行GC Roots Tracing 把剩下能关联到gcroot的对象找出来
3)重新标记
修正并发标记期间因用户程序继续运作而导致标记产生表动的那一部分对象的标记记录,这个阶段的停顿时间稍长点
4)并发清除
在这里插入图片描述

通过-XX:GCTimeRatio=告诉JVM最大暂停时间的目标值(以毫秒为单位)。 在运行时,吞吐量收集器计算在暂停期间观察到的统计数据(加权平均和标准偏差)。 如果统计表明正在经历的暂停其时间存在超过目标值的风险时,JVM会修改堆和GC设置以降低它们。 需要注意的是,年轻代和年老代垃圾收集的统计数据是分开计算的,还要注意,默认情况下,最大暂停时间没有被设置。
如果最大暂停时间和最小吞吐量同时设置了目标值,实现最大暂停时间目标具有更高的优先级。 当然,无法保证JVM将一定能达到任一目标,即使它会努力去做。 最后,一切都取决于手头应用程序的行为。
当设置最大暂停时间目标时,我们应注意不要选择太小的值。 正如我们现在所知道的,为了保持低暂停时间,JVM需要增加GC次数,那样可能会严重影响可达到的吞吐量。 这就是为什么对于要求低暂停时间作为主要目标的应用程序(大多数是Web应用程序),我会建议不要使用吞吐量收集器,而是选择CMS收集器。
(1)跟用户线程竞争资源
CMS 默认的并发线程数目为(CPU 数目+3)/4,当 CPU 线程大于 4 的时候,CMS 垃圾收集器至少要占用 25% 的资源。当小于 4 的时候占用 CPU 资源更加明显。
(2)无法清除浮动垃圾
当收集器在进行并发清除垃圾的时候,由于用户线程还在执行,要预留一定的空间给用户线程进行使用,所以收集器一定不能在老年代已经占用 100% 的情况下再进行垃圾收集。
(3)内存碎片
因为这个垃圾回收器是使用的标记-清除算法,所以会产生大量的内存碎片。
有两个值可以进行控制:
-XX:UseCMSCompactAtFullCollection 默认开启,来指定需要 FULL GC 时,会对内存空间进行一次整理。
-XX:CMSFullGCsBeforeCompaction 来指定多少次不整理之后进行一次整理。

G1收集器
https://www.cnblogs.com/lsgxeva/p/10231201.html

G1的设计原则就是简单可行的性能调优
开发人员仅仅需要声明以下参数即可:
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

G1 收集器有以下特点:
(1)空间整合:G1 收集器采用标记-整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次 GC。
(2)可预测停顿:这是 G1 的另一大优势,降低停顿时间是 G1 和 CMS 的共同关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型。能让使用者明确指定在一个长度为 N 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒,这几乎已经是实时垃圾收集器的特征了。

Young GC主要是对Eden区进行GC,它在Eden空间耗尽时会被触发。在这种情况下,Eden空间的数据移动到Survivor空间中,如果Survivor空间不够,Eden空间的部分数据会直接晋升到年老代空间。Survivor区的数据移动到新的Survivor区中,也有部分数据晋升到老年代空间中。最终Eden空间的数据为空,GC停止工作,应用线程继续执行。
Young GC 阶段:

阶段1:根扫描
静态和本地对象被扫描
阶段2:更新RS
处理dirty card队列更新RS
阶段3:处理RS
检测从年轻代指向年老代的对象
阶段4:对象拷贝
拷贝存活的对象到survivor/old区域
阶段5:处理引用队列
软引用,弱引用,虚引用处理

G1 Mix GC

Mix GC不仅进行正常的新生代垃圾收集,同时也回收部分后台扫描线程标记的老年代分区。

它的GC步骤分2步:

全局并发标记(global concurrent marking)
拷贝存活对象(evacuation)
在进行Mix GC之前,会先进行global concurrent marking(全局并发标记)。 global concurrent marking的执行过程是怎样的呢?

在G1 GC中,它主要是为Mixed GC提供标记服务的,并不是一次GC过程的一个必须环节。global concurrent marking的执行过程分为五个步骤:

初始标记(initial mark,STW)
在此阶段,G1 GC 对根进行标记。该阶段与常规的 (STW) 年轻代垃圾回收密切相关。
根区域扫描(root region scan)
G1 GC 在初始标记的存活区扫描对老年代的引用,并标记被引用的对象。该阶段与应用程序(非 STW)同时运行,并且只有完成该阶段后,才能开始下一次 STW 年轻代垃圾回收。
并发标记(Concurrent Marking)
G1 GC 在整个堆中查找可访问的(存活的)对象。该阶段与应用程序同时运行,可以被 STW 年轻代垃圾回收中断
最终标记(Remark,STW)
该阶段是 STW 回收,帮助完成标记周期。G1 GC 清空 SATB 缓冲区,跟踪未被访问的存活对象,并执行引用处理。
清除垃圾(Cleanup,STW)
在这个最后阶段,G1 GC 执行统计和 RSet 净化的 STW 操作。在统计期间,G1 GC 会识别完全空闲的区域和可供进行混合垃圾回收的区域。清理阶段在将空白区域重置并返回到空闲列表时为部分并发。

G1 常用参数
-XX:+UseG1GC 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis=200 设置期望达到的最大GC停顿时间指标(JVM会尽力实现,但不保证达到)
-XX:InitiatingHeapOccupancyPercent=45 启动并发GC周期时的堆内存占用百分比. G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45.
-XX:NewRatio=n 新生代与老生代(new/old generation)的大小比例(Ratio). 默认值为 2.
-XX:SurvivorRatio=n eden/survivor 空间大小的比例(Ratio). 默认值为 8.
-XX:MaxTenuringThreshold=n 提升年老代的最大临界值(tenuring threshold). 默认值为 15.
-XX:ParallelGCThreads=n 设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台不同而不同.
-XX:ConcGCThreads=n 并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同.
-XX:G1ReservePercent=n 设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10.
-XX:G1HeapRegionSize=n 使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.

[JVM-3]Java垃圾回收(GC)机制和垃圾收集器选择
https://www.cnblogs.com/Joy-Hu/p/10577103.html
垃圾回收器选择:串行收集器、并行收集器(吞吐量优先)、并发收集器(响应时间优先)
在这里插入图片描述

GC日志

每种收集器的日志形式都是由它们自身的实现所决定的,换言之,每种收集器的日志格式都可以不一样。不过虚拟机为了方便用户阅读,将各个收集器的日志都维持了一定的共性,就以最前面的对象间相互引用的那个类ReferenceCountingGC的代码为例:

虚拟机参数为“-XX:+PrintGCDetails -XX:+UseSerialGC”,使用Serial+Serial Old组合进行垃圾回收的日志

[GC [DefNew: 310K->194K(2368K), 0.0269163 secs] 310K->194K(7680K), 0.0269513 secs] [Times: user=0.00 sys=0.00, real=0.03 secs] 
[GC [DefNew: 2242K->0K(2368K), 0.0018814 secs] 2242K->2241K(7680K), 0.0019172 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System) [Tenured: 2241K->193K(5312K), 0.0056517 secs] 4289K->193K(7680K), [Perm : 2950K->2950K(21248K)], 0.0057094 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 2432K, used 43K [0x00000000052a0000, 0x0000000005540000, 0x0000000006ea0000)
  eden space 2176K,   2% used [0x00000000052a0000, 0x00000000052aaeb8, 0x00000000054c0000)
  from space 256K,   0% used [0x00000000054c0000, 0x00000000054c0000, 0x0000000005500000)
  to   space 256K,   0% used [0x0000000005500000, 0x0000000005500000, 0x0000000005540000)
 tenured generation   total 5312K, used 193K [0x0000000006ea0000, 0x00000000073d0000, 0x000000000a6a0000)
   the space 5312K,   3% used [0x0000000006ea0000, 0x0000000006ed0730, 0x0000000006ed0800, 0x00000000073d0000)
 compacting perm gen  total 21248K, used 2982K [0x000000000a6a0000, 0x000000000bb60000, 0x000000000faa0000)
   the space 21248K,  14% used [0x000000000a6a0000, 0x000000000a989980, 0x000000000a989a00, 0x000000000bb60000)
No shared spaces configured.

在这里插入图片描述

CMS和G1的异同:

  1. CMS是老年代垃圾收集器,需要配合Serial 或者ParNew年轻代垃圾收集器一起使用。
  2. G1 可以对整个堆进行垃圾回收。
  3. 使用G1垃圾回收器则堆内存的分配与其他情况不同,内存被分成若干个 Region区域 Region 可以存放年轻代的对像也可以存放老年代对象。还有专门的区域存放大对象。CMS的还是传统的年轻代老年代 eden from to的分区。
  4. 回收过程上不同,cms经历初始标记、并发标记、重新标记、并发删除四个阶段回收老年代。G1分youngGC和mixGC
  5. cms使用标记清除算法 G1使用复制算法

G1什么时候触发FullGC
G1 没有fullGC mixGC会清理年轻代和老年代

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值