JVM垃圾回收(二) 垃圾回收算法

谁践踏了优雅 2022-12-16 14:26 275阅读 0赞
  1. 标记清除算法

标记清除算法的优点在于速度足够快。但是缺点在于,对部分空间进行清除之后,这一整块的存储空间不连续,所以在这很容易造成内存碎片这种情况。

示意图如下:

在这里插入图片描述

  1. 标记整理算法

标记整理算法和前面的标记清除算法的区别在于多了一个步骤,这里会把内存空间进行整理,也就是说,在清除部分内存之后,会将内存往前移动,该算法的优点在于不会导致内存碎片,但是这种算法的速度比较慢。

示意图如下:

在这里插入图片描述

  1. 复制算法

复制算法:有两个内存空间,将第一个内存空间当中需要的内存区间进行复制到另一块的内存空间当中,到最后再将第二快的内存再一次返回给第一个内存空间当中。

复制算法的优点是不会有内存碎片,但缺点是需要占用双倍内存空间

示意图如下:

在这里插入图片描述

  1. 分代垃圾回收

示意图如下:

在这里插入图片描述
步骤如下:

  • 对象首先分配在伊甸园区域
  • 新生代空间不足时,触发 minor gc,伊甸园和 幸存区from 存活的对象使用 copy 复制到 幸存区to 中,存活的对象年龄加 1并且交换 幸存区from 和 幸存区to
  • minor gc 会引发 stop the world,暂停其它用户的线程,等垃圾回收结束(防止复制的时候变量的地址改变导致程序混乱),用户线程才恢复运行
  • 当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)
  • 当老年代空间不足,会先尝试触发 minor gc,如果之后空间仍不足,那么触发 full gc,STW的时间更长
  1. 相关VM参数

在这里插入图片描述

  1. GC 分析

使用以下代码段进行测试:给其划分内存空间。

  1. private static final int _512KB = 512 * 1024;
  2. private static final int _1MB = 1024 * 1024;
  3. private static final int _6MB = 6 * 1024 * 1024;
  4. private static final int _7MB = 7 * 1024 * 1024;
  5. private static final int _8MB = 8 * 1024 * 1024;

添加JVM的参数,运行代码查看输出 -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC

在这里插入图片描述
我们使用一个list数组,加入一个内存空间进去。使用代码段:

  1. ArrayList<byte[]> list = new ArrayList<>();
  2. list.add(new byte[_7MB]);

在前面设置了内存大小,在这内存不够,触发了垃圾回收机制,并且还可以看到伊甸园、幸存区 from 和幸存区 to 所占空间比例。

在这里插入图片描述
再往里面进行添加,是内存占用增大,再次查看伊甸园和幸存区 from 和幸存区 to 的所占比例,在这里伊甸园的空间基本上就已经占满了,

在这里插入图片描述
我们再添加一个512kb 进如这个list集合当中,可以发现这个时候新生代当中的数据对象会直接晋升到老年代当中。

在这里插入图片描述
以及当分配内存的时候,发现新生代当中的内存不够,而老年代当中的内存足够的时候,会直接晋升为老年代,以8m数据内存大小为例

在这里插入图片描述
当添加内存的时候,在新生代和老年代的内存都不够进行分配的时候就会抛出异常,也就是堆内存溢出。以添加两个8m的数据内存为例

在这里插入图片描述
但是当这段代码运行在线程当中,当内存不足的时候会不会影响到主线程直接结束,很显然是不会导致主线程结束,使用以下代码段进行测试

  1. new Thread(() -> {
  2. ArrayList<byte[]> list = new ArrayList<>();
  3. list.add(new byte[_8MB]);
  4. list.add(new byte[_8MB]);
  5. }).start();
  6. System.out.println("sleep....");
  7. Thread.sleep(1000L);

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,275人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM垃圾回收算法

    > 全文是在阅读了《深入理解Java虚拟机》进行的摘录笔记 标记-清除算法 算法分为“标记”和“清除”两个阶段:标记出所有需要回收的对象,在标记完成后,统一回收掉所有被

    相关 JVM垃圾回收算法

    Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法。 在Java堆上分配一个内存给实例对象时,此时

    相关 JVM 垃圾回收算法

    在说垃圾回收算法之前,先谈谈JVM怎样确定哪些对象是“垃圾”。 1.引用计数器算法: 引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器\+1

    相关 JVM垃圾回收算法

    前言 程序计数器,虚拟机栈,本地方法3个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出有条不紊地执行着出栈和入栈操作,每一个栈帧中分配多少内存,基本上是在类结