IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 内存与垃圾回收篇--15 垃圾回收相关算法 -B站尚硅谷JVM课程学习 -> 正文阅读

[Java知识库]内存与垃圾回收篇--15 垃圾回收相关算法 -B站尚硅谷JVM课程学习

标记阶段:引用计数算法

对象死亡:没有被任何活的对象引用
引用计数:对每个对象保存一个整型的引用计数器属性,用于记录对象被引用情况
优点:实现简单;判断效率高,回收没有延迟性
缺点:

  • 需要单独的字段存储计数器,增加存储开销
  • 每个赋值都要更新计数器,增加时间开销
  • 无法循环引用
    在这里插入图片描述
    Python使用引用计数算法进行垃圾回收,解决循环引用:
  • 手动解除
  • 弱引用

标记阶段:可达性分析算法

根搜索算法、追踪性垃圾收集
实现简单、执行高效、解决循环引用问题,防止内存泄露
实现思路:

  • 根对象集合(一组必须活跃的引用)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达
  • 使用可达性分析算法后,内存中的存活对象都会被根对象直接或间接连接,搜索所走过的路径称为引用链
  • 如果目标对象没有任何引用链,则是不可达的,表示对象已经死亡
  • 在可达性分析算法中,只有能够被跟对象集合直接或者间接连接的对象才是存活对象

GC Roots包含以下几类元素

  • Java 虚拟机栈中引用的对象
  • 本地方法栈(JNI)内引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁Synchronized持有的对象
  • JVM内部的引用
  • 反映JVM内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存
  • 临时性对象: 分代收集和局部回收

小技巧:由于GC Root采用栈方式存放变量和指针,所以如果一个指针,他保存了堆内存里面的对象,但是自己又不存放在堆内存里面,那它是一个Root

对象的finalization机制

对象的finalization机制:对象被销毁之前的自定义处理逻辑

  • 在垃圾回收之前,先调用finalize方法,允许被重写,用于对象被回收时进行资源释放

  • 永远不要主动调用对象的finalize方法
    1、导致对象复活
    2、调用时不保证马上执行,不发生GC,finalize方法将没有执行机会
    3、糟糕的finalize方法会影响GC性能

  • 虚拟机中对象一般处于是那种可能的状态
    1、 可触及的:从根节点可访问
    2、可复活的:对象所有引用都被释放,但对象可能在finalize中复活
    3、不可触及的:finalize调用,但没复活。finalize方法只会被调用一次。(垃圾)

  • 判断一个对象objA是否回收,至少经历两次标记过程
    1、如果objA到GCRoots没有引用链,则进行一次标记
    2、进行筛选,判断此对象是否必要执行finalize方法
    1)如果对象objA没有重写finalize方法,或者finalize方法已经被调用过,则objA不可触及的
    2)如果objA重写了finalize方法,且还没执行过,那么objA会被插入到F-Queue中,由一个VM自动创建的、低优先级的Finalizer线程触发finalize方法执行
    3)finalize方法是对象逃脱死亡的最后机会,稍后GC会对F-Queue中的对象进行第二次标记。如果objA在finalize方法中与引用链上的人一个对象建立了联系,则移除即将回收队列。

MAT(Memory Analyzer)与JProfiler的GC Roots溯源

获取dump文件:
jmap -dump:format = b,live,file = test1.bin pid
jvisualvm

package chapter15;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

public class GCRootsTest {
    public static void main(String[] args) {
        List<Object> numList = new ArrayList<>();
        Date birth = new Date();

        for (int i = 0; i < 100; i++){
            numList.add(String.valueOf(i));
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("数据添加完毕,请操作");
            new Scanner(System.in).next();
            numList = null;
            birth = null;

            System.out.println("numList,birth已置空,请操作");
            new Scanner(System.in).next();
            System.out.println("结束");
        }
    }
}

在第一次用户输入前导出一个dump文件,输入后在导出一个dump文件,导出过程为

  • 在cmd中输入jvisualvm 打开visualvm
  • 运行 GCRootsTest 代码
  • 点击堆dump 然后右键dump文件另存为(因为是个缓存文件)
    在这里插入图片描述
  • 使用MAT打开具体的dump文件

清除阶段:标记-清除算法(Mark-Sweep)

执行过程:
当堆中的有效空间被耗尽的时候,就会停止整个程序(Stop the world),然后标记,清除

  • 标记:从根节点出发,标记所有被引用的对象
  • 清除:对堆内存从头到尾进行线性遍历,清除所有没有被标记的对象

优点:基础常见
缺点:

  • 效率不高;
  • GC时要停止整个应用程序,用户体验差;
  • 清理出的空间不连续,产生内存碎片,需要维护一个空闲列表

何为清除?
不是真的置空,而是把清除对象的地址放在空闲列表中,新对象要放的时候会覆盖原有数据

清除阶段:复制算法

在这里插入图片描述
优点:

  • 没有标记清除过程,运行高效
  • 保证空间连续性

缺点:

  • 需要两倍的内存空间
  • G1这种分拆成大量region的GC,复制而不是移动,意味着GC需要维护region之间对象引用关系,不管是内存占用或者时间开销也不小

特别的:系统中垃圾对象比较多,复制算法要复制的存活对象较多,效率较低。新生代中使用较多,老年代中不适合使用

清除阶段:标记-压缩算法

又称为标记整理、Mark-Compact

在这里插入图片描述
执行过程:
标记阶段:同标记清除算法
整理阶段:将所有存活对象压缩到内存的一端,按顺序存放
又称为标记-清除-压缩,移动式的
优点:

  • 不需要使用空闲列表,直接指针碰撞
  • 消除内存减半的高额代价

缺点:

  • 效率上标记-整理算法低于复制算法
  • 移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址
  • 需要STW

小结

在这里插入图片描述
时间效率:复制最快
内存利用率:标记-清除、复制
内存整齐度:标记整理、复制
综合:标记整理好

分代收集算法

新生代:
对象生命周期短、存活率低、回收频繁-----复制算法
老年代:
对象生命周期长、存活率高、回收不及新生代频繁—混合

  • 标记阶段的开销与存活对象数量成正比
  • 清除阶段开销与所管理区域的大小成正比
  • 整理阶段开销与存活对象的数据成正比

增量收集算法、分区算法

增量收集算法:标记清除和复制算法
让垃圾收集线程和应用程序线程交替执行,处理线程间冲突
缺点:

  • 间断性执行应用程序代码,减少系统的停顿时间。但是,因为线程切换和上下文转换的消耗,会造成垃圾回收的总体成本上升,造成吞吐量下降

分区算法:将一个大的内存区域分割成多个小块,每个小区间独立使用,独立回收。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:18:55  更:2022-03-15 22:19:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:55:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码