【基础篇】十四、GC算法

文章目录

  • 1、实现思路
  • 2、SWT
  • 3、GC算法
  • 4、标记清除算法Mark Sweep GC
  • 5、复制算法Copying GC
  • 5、标记整理算法Mark Compact GC
  • 6、分代算法Generational GC
  • 7、分代的整体流程
  • 8、为什么分代GC把堆内存分为年轻代和老年代?📕

1、实现思路

Java实现垃圾回收的步骤:

  • 根据GC Root对象可达性分析,将内存中对象标记为存活的、可回收的
  • 处理可回收的对象,释放空间在这里插入图片描述

2、SWT

GC是在一个单独的线程,但不管JVM用哪种算法,都会存在一个阶段需要停止所有的用户线程,称Stop The World(STW),SWT大,用户用起来自然卡。

在这里插入图片描述

感受下SWT:

public class StopTheWorld {

    public static void main(String[] args) {
        /**
         * 启动用户线程和GC线程
         * 查看不同阶段用户线程的执行时间
         */
        new PrintTimeThread().start();
        new ClearThread().start();
    }
}

/**
 * 模拟用户代码,这里直接打印这段代码的执行耗时
 */
class PrintTimeThread extends Thread {
    @SneakyThrows  //lombok的try..catch
    @Override
    public void run() {
        long begin = System.currentTimeMillis();
        while (true) {
            long now = System.currentTimeMillis();
            System.out.println(now - begin);
            begin = now;
            Thread.sleep(100);
        }
    }
}

/**
 * 模拟GC线程
 */
class ClearThread extends Thread {
    @SneakyThrows
    @Override
    public void run() {
        List<byte[]> list = new LinkedList<>();
        while (true) {
            //存80个100M后就删除里面byte对象的强引用,垃圾回收释放
            if(list.size() >= 80){
                list.clear();
            }
            list.add(new byte[1024 * 1024 * 100]);
            Thread.sleep(100);
        }
    }
}

添加JVM参数,使用分代回收的垃圾回收器,输出GC详细信息,并限制堆最大10G:

-XX:+UseSerialGC -Xmx10g -verbose:gc

运行发现用户线程本来100ms左右的事儿,有时候会被拖到2000ms以上:

在这里插入图片描述

3、GC算法

对象回收算法的评价标准:

  • 吞吐量 = 执行用户代码时间 /(执行用户代码时间 + GC时间),值越大,性能越高
  • 最大暂停时间:SWT的最大值

在这里插入图片描述

  • 堆的使用效率:如复制算法只用一半空间

在这里插入图片描述

以上三个指标,不可兼得。各个算法各有长处,对应着不同的适用场景。

4、标记清除算法Mark Sweep GC

实现:

  • 从GC Root List开始,遍历引用链,找到可达对象,并标记
  • 清除没标记的对象

在这里插入图片描述

优点:

  • 实现简单,只需给对象维护个标记位

缺点:

  • 导致内存碎片化:从原本连续的内存空间,摘掉一些被回收的,得到一些碎片。如下回收了4+3+2,却连个5字节的对象都创建不了

在这里插入图片描述

  • 分配速度慢:由于内存碎片化,需要维护一个空闲链表记录可用空间,新对象来了每次都得往后遍历,找出一块合适大小的地儿安置

在这里插入图片描述

5、复制算法Copying GC

实现:

  • 堆内存一分为二,一半叫From,一半叫To
  • 新对象来了往From安置
  • GC时,把From的存活对象Copy到To

在这里插入图片描述

  • 清掉From,From和To名字互换,原来的To做为新的From安置新new的对象

完整例子:

  • 开始状态:

在这里插入图片描述

  • GC开始,把GC Root对象和可达的对象搬到To空间
    在这里插入图片描述

  • 清掉From空间,并把原来的To改为From空间
    在这里插入图片描述

一句话:将存活的对象搬运到另一块空间,清理掉当前空间,互换名字

优点:

  • 解决了内存碎片化:往To搬的时候,按连续地址往过码
  • 吞吐相比下面的标记整理算法要高:只需遍历一次存活对象。但不如标记-清除算法,因为后者不用给对象搬家

缺点:

  • 堆内存使用率低:安置新对象只能用50%的堆空间,另一半得留着To

5、标记整理算法Mark Compact GC

也称标记压缩,用来解决标记清除算法的内存碎片化缺点。

实现:

  • 从GC Root开始,遍历标记可达对象
  • 将可达的存活对象移动到堆的一端,清掉非存活的

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

  • 无内存碎片化问题:比标记清除多了一步整理
  • 堆内存利用率比复制算法高

缺点:

  • 理解阶段性能不高,得看整理阶段的实现算法

6、分代算法Generational GC

组合使用了上面的几种算法,被主流使用。分代即把内存分为年轻代和老年代:

在这里插入图片描述

关于这几块空间的大小设置:

在这里插入图片描述

Demo:

public class Gc {
    @SneakyThrows
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        int count = 0;
        while (true) {
            System.in.read();
            System.out.println(++count);
            list.add(new Byte[1024 * 1024]);
        }
    }
}

对应JVM的参数:

-XX:+UseSerialGC -Xms60m -Xmn20m -Xmx60m -XX:SurvivorRatio=3 -XX:+PrintGDetails

粗略计算:老年代60m - 20m = 40m,Eden除以随便一块s区 = 3,则Eden:s0:s1 = 12:4:4,使用阿尔萨斯执行memory验证:

在这里插入图片描述

7、分代的整体流程

  • 新new的对象,安置到堆的年轻代的伊甸园区

在这里插入图片描述

  • 伊甸园区满了以后,触发GC,仅是年轻代的GC(Minor GC、Young GC)
  • 把Eden的存活对象放入S1(To),Eden区被清空(复制算法)

在这里插入图片描述

  • 互换名,S0做为To,S1做为From,再安置新对象,直到Eden和From满

在这里插入图片描述

  • 再次触发Minor GC,Eden和From存活对象放入S0,其余清掉回收(每次GC能活下来的,记录年龄,+1)

在这里插入图片描述

  • 对象GC年龄到达阈值(最大15,对象头里放着,默认值和垃圾回收器有关),晋升到老年代。(一直活着就别在From和To之间来回搬了)

在这里插入图片描述

  • 老年代最后也满了,新new的对象进来,先Minor GC,还是不足,再Full GC,对整个堆进行垃圾回收,此时的STW时间就比Minor GC时的SWT长一些了

在这里插入图片描述

  • Full GC后,无法回收老年代对象,再往老年代放,就OOM

在这里插入图片描述
补充:如果现在新生代已经满了,Minor GC还是满,再来对象,尽管新生代有的对象没到达年龄阈值,也会被搬到老年代

8、为什么分代GC把堆内存分为年轻代和老年代?📕

在这里插入图片描述
从上面的GC分代流程就可以看到一个最核心的点:只给年轻代GC,STW时间更短了,这是明摆着的好处。

答案:

  • 分代GC下,可以只进行Minor GC,不用每次Full GC,STW时间短
  • 开发者可以通过调整年轻代和老年代的比例来适应不同的服务场景,提高性能(对象用完即丢的,生命短的多,可以调大年轻代,目的就是少STW,非STW的,也能Minor就别Full)
  • 年轻代和老年代可以选择使用不同的算法,年轻代通常用复制算法、老年代则用标记清除或者标记整理

在这里插入图片描述

补充:

  • 很多对象都是new完很快就可以回收,比如一个个Vo
  • 老年代存放一直用的对象,比如Spring容器里的一些Bean
  • JVM默认设置下,新生代空间远小于老年代

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/294232.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

除了AIGC和大模型,2023年这个赛道也很拥挤

大数据产业创新服务媒体 ——聚焦数据 改变商业 转眼间&#xff0c;2023年即将里过去。回首往事&#xff0c;这个疫情后的第一个年份还是超乎不少人预期&#xff0c;这其中最明显的、最引人关注的科技变革&#xff0c;就是人工智能。自从年初ChatGPT爆火以来&#xff0c;这个话…

Unity SRP 管线【第五讲:自定义烘培光照】

文章目录 一、自定义烘培光照1. 烘培光照贴图2. 获取光照贴图3. 获取物体在光照贴图上的UV坐标4. 采样光照贴图 二、自定义光照探针三、 Light Probe Proxy Volumes&#xff08;LPPV&#xff09;四、Meta Pass五、 自发光烘培 一、自定义烘培光照 细节内容详见catlikecoding.c…

iPay88 支付网关Gateway-User Scan(用户扫码模式 - PHP实现)

背景 近期因为合作客户有马来西亚的业务&#xff0c;需要对接 【iPay88 支付】 通过阅读官方文档&#xff0c;发现一头雾水 相对之前接触的支付文档&#xff0c;个人觉得 iPay88 是最凌乱的 注意&#xff0c;注册平台账号后&#xff0c;会邮件发送几个开发文档附件&#xff08;…

TikTok革新游戏规则:解读短视频对社交媒体的影响

在社交媒体的巨浪中&#xff0c;TikTok以其独特的短视频形式和强大的创意社区&#xff0c;重新定义了游戏规则。这个以15秒视频为核心的平台&#xff0c;不仅让用户获得了表达自我的新方式&#xff0c;更深刻地影响了社交媒体的演进。本文将深入解读TikTok对社交媒体的影响&…

OpenSSL——升级

OpenSSL&#xff08;Open Secure Sockets Layer&#xff09;是一个开源的软件库&#xff0c;提供了SSL和TLS协议的实现&#xff0c;用于加密通信。它广泛用于安全连接&#xff0c;例如在网站上通过HTTPS协议进行安全的数据传输. 但是从openssl申请道德证书是不安全的。对于网站…

打破闲鱼商品搜索瓶颈!云端电商API接口让你畅享商品详情关键词搜索的便利!

在闲鱼卖家的日常经营中&#xff0c;商品搜索是一个至关重要的环节。但是&#xff0c;由于闲鱼平台商品信息繁杂&#xff0c;卖家往往很难通过手动搜索的方式找到符合自己需求的商品。为了解决这一问题&#xff0c;云端电商API接口应运而生。联讯数据将详细介绍云端电商API接口…

第一届能源电子产业创新大赛太阳能光伏赛道决赛及颁奖仪式在宜宾成功举办

在工业和信息化部电子信息司指导下&#xff0c;由工业和信息化部产业发展促进中心和宜宾市人民政府主办&#xff0c;宜宾市经济和信息化局、宜宾高新技术产业园区管理委员会承办的第一届能源电子产业创新大赛太阳能光伏赛道决赛及颁奖仪式于2024年1月3日-5日在宜宾市成功举办。…

亲授秘籍!独立站推广神级攻略,不信你试试?

在电商市场竞争激烈的今天&#xff0c;对于跨境电商卖家而言&#xff0c;有效推广独立站已经成为了一项关键任务。为了提升品牌知名度和吸引更多的潜在客户&#xff0c;我们需要不断探索新的推广方式和策略。在本文中&#xff0c;龙哥将分享一些成功的推广经验&#xff0c;以下…

java 6种深拷贝集合方式及其性能差异对比

文章目录 ArrayList 构造方法拷贝运行1000次耗时 1ms for循环拷贝运行1000次耗时 14ms Stream流 collect实现拷贝运行1000次耗时 54ms Stream流spring的BeanUtils实现拷贝运行1000次耗时 2468 ms Hutool工具实现拷贝Hutool 5.7.13版本运行1000次耗时 64674 msHutool 5.8.24版本…

芯片金线包封胶的使用注意事项是什么?

芯片金线包封胶的使用注意事项是什么?金线包封胶是一种高性能、高粘度的密封胶&#xff0c;广泛应用于电子、电器、汽车等领域。它具有良好的防水、防潮、防震等性能&#xff0c;能够保护产品内部零件不受环境影响&#xff0c;提高产品的使用寿命。然而&#xff0c;在使用金线…

记一次RabbitMQ服务器异常断电之后,服务重启异常的处理过程

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 机房突然停电&#xff0c;rabbitmq的主机异常断电&#xff0c;集群服务全部需要重启。但是在执行service…

热泵,预计到2025年市场规模将达到650亿美元

热泵是一种利用空气、水、地热等低品位能源&#xff0c;转化为高品位热能&#xff0c;提供供暖、热水和冷却等服务的热力设备。近年来&#xff0c;热泵市场逐步发展壮大&#xff0c;成为新能源市场的重点发展领域。全球市场分析&#xff1a; 近年来&#xff0c;全球绿色环保理念…

QT上位机开发(动态库dll的开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 有的时候&#xff0c;我们不想把所有的代码都放在一个exe里面&#xff0c;这个时候我们就需要引入dll动态库的概念。在windows平台上面&#xff0c…

接口测试测什么?一个简单问题把我难住了!

那么设计测试用例时我们主要考虑如下几个方面&#xff1a; 01、功能测试 接口的功能是否正确实现了 接口是否按照设计文档中来实现 &#xff08;比如username参数写为了user&#xff0c;那么这就不符合&#xff0c;因为接口文档在整个开发中都需要使用&#xff0c;所以接口实…

Spss Amos 28安装包下载及安装教程

Amos 28下载链接&#xff1a;https://docs.qq.com/doc/DUnhwUXFnTGtyRnJ1 1.鼠标右键解压到“Amos 28” 2.选中Setup&#xff0c;鼠标右击选择“以管理员身份运行” 、3.点击“Next” 4.选择I accept the terms in the license agreement&#xff0c;点击“Next” 5.选择软件安…

Centos7.9或Deebian12安装K3s和k9s详细流程

1、在线安装k3s 安装的版本为&#xff1a;v1.23.15k3s1 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRRORcn INSTALL_K3S_VERSION"v1.23.15k3s1" sh - 2、安装完成&#xff0c;测试 kubectl get nodes正常输出即没…

【教学类-综合练习-02】20231208 大3班 数字加减法练习(数字火车、X—Y加法减法、X乘法、X—Y数字分合)

教学情况 时间&#xff1a;20231208 班级&#xff1a;大3班 人数&#xff1a;21 目的&#xff1a;幼儿根据自己的能力水平&#xff0c;选择适合的数学题&#xff08;多款样式&#xff09; 在昨天大4班制作的基础上&#xff0c;特地打印一些小纸片数学题&#xff08;节省纸…

WPF DatePicker与Calendar的使用和样式修改

什么是DatePicker&#xff0c;Calendar Calendar&#xff1a;日历&#xff08;显示年月日视图控件&#xff09;DatePicker&#xff1a;日期选择器&#xff08;是一个更小的控件&#xff0c;点击控件时才会弹出一个日历&#xff09; Calendar使用 常用属性 DisplayMode&#…

【漏洞复现】通天星CMSV6车载监控平台FTP匿名访问

Nx01 产品简介 深圳市通天星科技有限公司&#xff0c;是一家以从事计算机、通信和其他电子设备制造业为主的企业。通天星车载视频监控平台软件拥有多种语言版本。应用于公交车车载视频监控、校车车载视频监控、大巴车车载视频监控、物流车载监控、油品运输车载监控、警车车载视…

基于Java SSM框架实现宠物管理系统项目【项目源码+论文说明】

基于java的SSM框架实现宠物管理系统演示 摘要 随着我国经济的快速发展&#xff0c;人民生活水平的不断提高&#xff0c;宠物逐渐成为许多宠物爱好者的一种生活方式。 宠物的品种也越来越多样化&#xff0c;宠物不仅能给生活带来乐趣还可以成为空巢老人&#xff0c;独生子女很…