JVM-GC算法

1> Class 类加载

主动加载的几种情况:
  • Student student = new Student(); 最常用的方式

  • 反射或者clone的方式

  • 初始化子类的时候,父类会被优先初始化。

  • 调用一个类的静态方法。

类的加载分为5步:
  • 加载 ClassLoader

    1> 全路径名称,获得类的二进制数据流。

    2> 解析类的数据流,转化为方法区(永久代、元空间)内部数据结构。

    3> 创建Class类的实例。

  • 验证

    4步的:格式、语义、字节码、符号引用

符号引用:

直接引用:

  • 准备

    虚拟机会为这个类分配相应的内存空间。

  • 解析

    符号引用转化为直接引用了。

  • 初始化

    把类加载到系统中,这个时候,类才会开始执行java字节码。

2> 栈针操作

1>java栈线程私有的。

2>每次函数的调用都是通过栈传递的。

3>先进后出。每次方法调用的时候——>入栈; 每次方法执行完毕的时候——>出栈。

4>局部变量表、操作数栈、帧数据区。

3> 垃圾回收算法

3.1> 可触及性——判断垃圾
  • 可触及

    从根节点开始,可以到达某个对象。

  • 可复活

    finalize()

  • 不可触及

    finalize()只会执行一次,错过了这个复活机会,那么就是不可触及的状态。

3.2> 引用级别(常见面试题)

一共四个级别:

  • 强引用

    Student student = new Student();

  • 软引用(java.lang.ref.SoftReferenct)

    堆空间不足的,才会被回收。

  • 弱引用(java.lang.ref.WeakReferenct)

    GC的时候,只要发现存在弱引用,无论系统堆空间是否不足,都会被回收。

  • 虚引用

    跟没有引用是一样的。

讲完了触及性和引用级别,我们来看一道面试题LocalValueGC.java

槽位复用

3.3> 垃圾回收算法

6大垃圾回收算法,分别是:

1> 计数法
  • 它是最古老的垃圾收集方法。
  • 有问题的
    • 循环引用。
    • 性能问题。
2> 标记清除法

现代垃圾回收算法的思想基础

  • 优点

    • 实现简单。
    • 与保守式GC算法相兼容的。(保守式GC算法中,对象是不能被移动的)
  • 缺点

    • 内存的空间碎片化。
    • 分块是不连续的,遍历空闲的链表。如果分配大对象的时候,最差的情况,可能是在最后才找到合适的内存空间进行分配。
  • 保守式GC

    不能识别的指针和非指针的GC。

    优点:

    ​ 1> 语言处理程序步依赖于GC的。简单。

    缺点:

    ​ 1> 识别指针和非指针是需要付出成本的。

    ​ 2> 错误识别指针会压迫堆。

    ​ 3> 能够使用的GC算法有限。

3> 复制算法

为了解决效率问题和空间碎片问题,而产生的。

  • 优点
    • 执行效率高
    • 没有内存碎片
  • 缺点
    • 内存空间只能使用1/2

复制算法在JVM堆中的应用

新生代:Eden——S0——S1 8:1:1 可以使用的空间Eden+S0= 8+1=90% 可以使用的空间 S1=10% 不可以使用的空间

-XX:SurvivorRatio

进入老年代:

  • 设置BIgObject -XX:PretenureSizeThreshold
  • 设置OldObject -XX:MaxTenuringThreshold
4> 标记压缩算法
  • 老年代的算法。
  • 在标记清除算法的基础上进行的优化。性价比很高。
  • 不会产生内存碎片
5> 分代算法

新生代——>复制算法

老年代——>标记清除、标记整。

6> 分区算法

将整个堆空间,划分成多个小的空间,然后针对垃圾比例较高的空间,执行GC回收。这样,可以提升一次GC的耗时。

4> 垃圾收集器

1> 串行回收器
  • Serial回收器,单线程,独占式。它是最古老的回收器

  • 在JDK1.3之前,它是新生代收集器唯一的选择。

  • client模式下,是默认的新生代收集器。

  • 单线程的。特点:单核/内核少的计算机来说,它的性能表现很好。简单高效

  • -XX:+UseSerialGC指定新生代&老年代都是用串行回收器。

  • 新生代——>复制算法。 老年代——>标记压缩算法。

2> 并行回收器
  • 独占式的。与串行回收器唯一不同的就是,多线程并发的。

  • 如果单核/内核少的计算机来说,它的性能不如串行回收器。

  • -XX:ParallelGCThreads=8(默认值),当我们CPU的数量少于8的时候,并行8。 如果大于8,并行线程数量3+(5*cpu_nums/8)

  • CMS(关心系统的停顿时间)

    1>初始标记 STW

    ​ 标记根对象。

    2>并发标记

    ​ 标记所有对象。

    3>预清理

    ​ 清理前的准备和控制停顿时间,可以被关闭的。

    4>重新标记 STW

    ​ 预测下一次新生代发生GC的时间,然后取中间时刻。

    ​ 目的:尽量避免新生代GC和重新标记重叠执行。从而减少一次停顿时间。

    5> 并发清理

    ​ 真正的执行类清理操作

    6>并发重置

    ​ 收尾的工作。

    缺点:内存碎片。

    -XX:+UserCMSCompactAtFullCollection : 指定GC后,进行一次碎片整理。

    -XX:+CMSFullGCsBeforeCompaction:指定执行多少次GC后,进行一次碎片整理。

3> G1回收器

3.1>新生代GC

* 主要的工作就是回收Eden取和Servivor区。

3.2>并发标记周期

  • 初始标记 STW

    标记从根节点直接可到达的对象。

  • 根区域扫描

    扫描survivor区可以直达老年代的对象。

  • 并发标记

    再次扫描堆的存活对象。再次进行了确认标记。

  • 重新标记 STW

    由于并发标记阶段,应用程序也是并发的。那么这个阶段,会对标记的结果进行最后的修正。

  • 独占清理 STW

    计算各个区域的存活对象和GC回收比例。然后进行一个比例的排序。供混合收集使用。

  • 并发清理

    取识别并清理哪些完全空闲的区域。

3.3>混合收集

  • 回收垃圾比例较高的区域。(减少每次GC时间)
  • 新生代和老年代GC都会同时执行。那么被清理区域中的存活对象就会被移动到其他区域。(减少内存碎片)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值