GC演变过程、三色标记法、大白话讲解G1

news2024/11/21 0:17:57

文章目录

    • GC演变过程
    • 并发垃圾回收需要解决的问题
      • 怎么确定一个垃圾?
      • 并发收集存在的问题
    • 三色标记法
    • CMS垃圾收集器
    • G1垃圾收集器
      • 介绍,主要特点
      • 优点
      • 使用注意点

GC演变过程

在Java中,垃圾收集一直是一个非常重要的组成部分, 到目前为止,垃圾收集器已经有十种了, 在不停的优化.

在这里插入图片描述

那为什么需要不停的优化呢? 其实根本在于Java程序使用的内存在不断的增加, 在最开始的时候就只有几兆,几十兆, 使用串行垃圾回收器不会浪费多多少时间, 后来慢慢发展, 到现在有的Java程序需要占用几十G的内存,那使用串行垃圾回收肯定就不适用了.

在这里插入图片描述
到目前为止, 这十种垃圾回收器其实总共可以分为三类.这里举例进行说明.

  1. 串行垃圾回收
    你、你女朋友、你男朋友在房间里扔线团(垃圾)玩, 玩了一段时候后, 你妈妈看见房间里垃圾太多了, 说不许动(STW), 然后进来帮你们收拾垃圾.收拾完出去,你们又可以继续玩了.
  2. 并行垃圾回收
    还是你、你女朋友、你男朋友在房间里扔线团(垃圾)玩, 但是后来你们生活改善了, 换了个200平的大房子, 现在你妈妈一个人打扫就太慢了, 就和你爸爸一起帮你们打扫, 当然打扫的时候,你们还是不能动.
  3. 并发垃圾回收
    每次你爸妈帮你们收拾垃圾的时候你们都不能动, 这个让你们很不爽, 感觉玩的不高兴, 于是和你爸妈反馈, 你爸妈为了满足你, 给你们雇了一个保姆, 就一直在你们房间, 一旦你们产生垃圾, 就帮你们进行处理, 就这样你们可以一边玩, 还有人帮你们收拾, 就一直可以玩了.

看到这几个样例,相信能很容易理解这几类的区别了.其实垃圾回收还有一个一直在优化的点. 就是STW(stop the word),对于web应用, 是非常关注这一点的, 因为如果在外部请求到来, 你的程序正好在垃圾回收, 花费了好几秒, 那就很影响客户体验了, 并发垃圾收集器就是为了解决这一点, CMS和G1都属于并发垃圾收集器.

在这里插入图片描述

并发垃圾回收需要解决的问题

怎么确定一个垃圾?

我们怎么确定一个对象是不是垃圾呢? 其实就是可达性分析.

通常通过建立根对象的集合,然后检查从这些根对象开始的可触及性来实现,如果正在运行的程序可以通过根对象访问到某个对象,那么这个对象就是可触及的,而无法被触及的对象被认为是垃圾.

跟对象的集合通常通过包括下面几个部分:

  1. 虚拟机栈中的局部变量的对象引用
  2. 传入本地方法栈中,没有被释放的对象引用.
  3. 方法区中的常量引用的对象.
  4. 方法区中的静态变量引用的对象.

具体实现就是从根节点开始有一个对象引用图,在追踪的过程中以某种方式打上标记,当追踪结束时,为被标记的对象就是无法触及的.

对应到我们生活中举的例子,我们往房间里扔线团, 那有线的就是正常的, 没线的就是垃圾.

并发收集存在的问题

在业务线程不断的产生垃圾的同时, 垃圾回收线程会不断的进行标识, 标识哪个对象是有用的

那我们知道线程是靠CPU调度的, 一个线程不可能一直执行, 当垃圾回收线程被挂起的时候, 已经标识好的对象的状态是有可能被改变的.遍历结束后,所有未被标记的对象都是垃圾对象,可以被回收。

比如一个对象被标识成垃圾, 然后垃圾回收线程被挂起了, 在被挂起的时候, 这个对象又重新被业务线程引用了, 又不是垃圾了, 哪这种怎么处理?

这时候就出现了一种算法, 叫做三色标记法.

三色标记法

三色标记法(Tri-color marking)是一种用于垃圾回收的算法。

它的主要思想是将所有对象分为三种颜色,所有的对象开始的时候都是白色,从程序的根集(如全局变量或寄存器)开始,逐步遍历所有与之相关联的对象,并将它们标记为灰色或黑色。

三种颜色的区别是:

  • 白色: 还没有被访问到

  • 灰色: 被访问到还没有完成, 比如说当前节点被访问是有引用, 但是它的孩子节点(成员变量)还没有被访问, 或者说该节点有三个孩子,其中有两个孩子被访问完成, 另一个还没有被访问到,也是灰色.

  • 黑色: 被访问且完成, 当前节点和他所有的孩子节点都被访问到(不包括孙子).

在这里插入图片描述

之前我们说在标识的过程中, 对象的状态可能会发生变化, 接下来我们就来分析一下, 其实总结来说, 可能会发生三种变化, 还是以A、B、D这三个对象来说.

  • 情况一: B->D消失.
    在这里插入图片描述
    这种情况其实没什么影响, 如果是垃圾引用消失就刚好被删除, 如果不是垃圾, 还有别的对象需要该引用, 那必然通过别的对象能够找到, 也不会被删除.

  • 情况二.A-D增加.
    在这里插入图片描述
    这种情况也没有影响, 因为B还是灰色, 还会扫描, 也能扫描到D.

  • 情况三: B-D消失, A->D增加
    在这里插入图片描述
    这种就会有影响了, 因为A对象是黑色的, 不会再扫描, B到D的引用又消失了, 那此时D就会被当做垃圾, 但是它不是, 明明还有对象A引用到它.

那这个问题怎么解决呢?

CMS解决方案:Incremental Update Reference
简单一句话就是当黑色对象指向白色对象, 将黑色对象标灰
那怎么知道黑色对象值向白色对象了呢?通过写屏障, 可以理解为一个切面操作,类似Spring里的AOP这些, 监测所有的引用变化,发现是黑色指向白色,那就把它变成灰色.

G1针对此问题的解决方案:SATB
简单来说就是做一个快照,还是监测所有的引用变化, 当发现灰色到白色的线消失时, 把这个引用存到专门的GC堆栈中.
然后回收线程需要对这个GC堆栈中的引用做特殊处理,就是看看有没有其他的对象需要这个引用,没有的话就是垃圾了.
在这里插入图片描述

CMS垃圾收集器

CMS是为了解决STW的第一次尝试. 也是使用并发垃圾收集的第一款垃圾收集器.

虽然CMS为了解决STW产生,但是很多长时间的STW却是由于CMS诞生的,为什么呢?

因为CMS中的垃圾回收是在某一阀值的时候开始回收,回收阀值可用指定的参数进行配置,-XX:CMSInitiatingOccupancyFraction来指定,默认为68,也就是说当老年代的空间使用率达到68%的时候,会执行CMS回收。如果内存使用率增长的很快,在CMS执行的过程中,已经出现了内存不足的情况,此时CMS回收就会失败,虚拟机将启动老年代串行回收器进行垃圾回收,这会导致应用程序中断,直到垃圾回收完成后才会正常工作,这个过程GC的停顿时间可能较长,所以-XX:CMSInitiatingOccupancyFraction的设置要根据实际的情况.

G1垃圾收集器

介绍,主要特点

终于迎来了今天的主角, G1,目前G1已经在很多生产环境中使用了, 可以大胆的学习使用.

在之前的垃圾收集器其实都是分代的,就是有明确的新生代, 老年代, 不同的垃圾收集器负责不同的代.

而G1最关键的点,也是和之前最大的不同:
物理上是分区的,逻辑上是分代的

怎么理解?就是它实际会把内存分为一块一块的,也就是物理上分区, 但是每一块都可以动态的作为Eden区,Survivior,Old区.这个视实际情况而定.

比如,某个项目新对象很多,且产生特别快, 那就把Eden区分的多一些
比如说有的项目,老年代对象多, 且需要持续使用, 不够用, 那就把Old区分的多一些.

在这里插入图片描述

这样还有一个好处, 就是一小块一小块进行处理,比整体处理效率更高.
比如某一小块区域快满了,就把它清掉, 不需要等整体满了再去清.

优点

在这里插入图片描述

使用注意点

  1. 不建议手工指定新老年代比例.当指定之后,G1的自动调优功能就完成不了了.

在这里插入图片描述

  1. 一般使用内存大于等于8g才建议使用G1.
    因为它需要维护大量的数据结构来追踪每个区域的垃圾回收情况。这些数据结构需要占用额外的内存空间,对于小型应用程序来说可能会造成内存不足的问题。

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GoogleTest之Actions的用法

目录 返回值Actions的组合验证复杂参数mock副作用改变mock对象的行为设置返回类型的默认值使用自定义函数作为Actions 通用示例 namespace mock_action { class Foo { public:virtual ~Foo() {}virtual int& GetBar() 0; // 1virtual int GetPointerValue() 0; //…

Linux CentOS7虚拟机配置静态IP并允许上网的配置方法

文章目录 前言一、开启本地电脑VMnet8二、Linux配置静态IP1. NAT模式设置2. 开启虚拟机登录root用户3. 执行命令设置静态IP4. 重启网卡① 重启网卡 (正常)② 重启网卡 (异常)③ 解决方式:禁用NetworkManager 5. 查看ip6. 本地电脑cmd窗口ping虚拟机7. 虚拟机ping本地…

Golang每日一练(leetDay0095) 第一个错误的版本、完全平方数

目录 278. 第一个错误的版本 First Bad Version 🌟 279. 完全平方数 Perfect Squares 🌟🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日…

springboot的数据访问和数据视图

当使用 Spring Boot 进行数据访问时,我们可以选择使用 MyBatis 或 JPA(Java Persistence API)来实现增删改查操作。下面我将分别给出使用这两种方式整合数据访问的详细步骤和示例,同时结合 Thymeleaf 实现数据展现。 方式一: 使用…

AI实战营:语义分割与MMSegmentation

目录 OpenMMLab图像分割算法库MMSegmentation 深度学习下的语义分割模型 全卷积网络Fully Convolutional Network 201 ​编辑 上下文信息与PSPNet模型 空洞卷积与DeepLab模型 语义分割算法总结 语义分割 前沿算法 SegFormer K-Net MaskFormer Mask2Former Seg…

PySide2 or PyQt5???该如何抉择???

1. 区别 Qt库里面有非常强大的图形界面开发库,但是Qt库是C语言开发的,PySide2、PyQt5可以让我们通过Python语言使用Qt。 但是 PySide2、PyQt5 这两者有什么区别呢? 可以形象地这样说: PySide2 是Qt的 亲儿子 , PyQt5 …

面向对象程序设计|静态友元

题目一:复数运算 题目描述: 复数类的声明如下 要求如下: 1. 实现复数类和友元函数addCom和outCom; 2. 参考addCom函数为复数类增加一个友元函数minusCom,用于实现两个复数的减法; 3. 在main函数中&…

待办事项JS:DHTMLX To Do List 1.2 cRACK

DHTMLX To Do List用于有效任务管理的DHTMLX JavaScript 待办事项列表 使用 JavaScript/HTML 5 中的待办事项列表来管理您的任务并确定其优先级。将组件连接到 DHTMLX 甘特图,并允许用户以简单直观的方式快速组织他们的业务流程。 DHTMLX JavaScript 待办事项列表的…

chatgpt赋能python:Python建模块最佳实践

Python建模块最佳实践 Python是一种灵活、易于使用的编程语言,因其强大的模块化支持和丰富的第三方模块而备受推崇。本文将介绍Python建模块的最佳实践,以便帮助开发人员创建可重用、可维护和易于测试的Python模块。 基本概念 在Python中,…

创业很长时间以后…

创业过很长时间以后…综合能力是有滴 创业和打工后的思维习惯 为了效率,一般情况是这样滴 趣讲大白话:区别还是有滴 【趣讲信息科技195期】 **************************** 创业还是很难滴 每年成立很多新公司 有很多公司关门 公司平均生存时间&#xff1…

右值引用以及move移动语义和forward 完美转发

右值引用 右值引用最简单的作用:可以避免无谓的复制,提高了程序性能(在移动构造函数中有体现)。 什么是右值 最基本的解释: 左值可以取地址、位于等号左边; 右值没法取地址,位于等号右边。&…

UnityVR--组件9--VideoPlayerAudioSource

目录 前言 视频组件VideoPlayer参数解释 RenderMode渲染方式 VideoPlayer类中的API 音频组件AudioSource参数解释 AudioSource类中的常见API&简单应用 前言 在之前的VR场景中已经使用过VideoPlayer播放视频(Unity.UI的交互(6)-播放…

chatgpt赋能python:Python怎么快速读取一组图片的RGB值?

Python怎么快速读取一组图片的RGB值? 简介 Python是一种非常流行的程序设计语言,它具有易于学习、简洁明了的语法和强大的功能。Python被广泛应用于数据分析、人工智能、科学计算、Web开发、游戏开发等领域。在这篇文章中,我们将介绍如何使…

chatgpt赋能python:Python快速缩进技巧与优化提升

Python快速缩进技巧与优化提升 介绍 在Python中,缩进是代码块的唯一标识符。这种缩进机制使得Python代码看起来更加清晰和易于阅读。同时,正确的缩进也是Python程序能否正常运行的重要因素。然而,大量的缩进可能会导致程序员的效率降低&…

Android系统Handler详解

目录 一,背景介绍 1.1 简介 1.2 核心概念 1.3 Handler 背后的生产者-消费者模型 二,Handler机制原理 2.1 消息模型 2.2 Handler原理概述 2.3 Handler与管道通信 三,实战 3.1 创建 Handler 3.2 子线程向主线程 3.3 主线程向子线程…

C/C++爱心代码“你把握不住的,让哥来~”祝你找到另一半

目录 第一种心形 加点好玩的 最后一忠心形&#xff08;会变色的爱心&#xff09; 618多得图书活动来啦 第一种心形 这次需要用到头文件#include<windows.h> #include<stdio.h> #include<windows.h> 以下是完整代码 #include<stdio.h> #include<…

chatgpt赋能python:Python中如何使用Math库进行数学计算

Python中如何使用Math库进行数学计算 Python是一种功能强大的编程语言&#xff0c;但对于许多数字计算、三角函数和其他复杂的数学问题&#xff0c;Python本身并不提供内置支持。为了解决这些问题&#xff0c;Python提供了一个名为Math的库。本文将介绍如何引入Math库&#xf…

【王道·操作系统】第三章 内存管理【未完】

一、内存管理 1.1 内存的基础知识 内存可存放数据&#xff0c;程序执行前需要先放到内存中才能被CPU处理——缓和CPU与硬盘之间的速度矛盾内存地址从0开始&#xff0c;每个地址对应一个存储单元 按字节编址&#xff1a;每个存储单元大小为1字节(B)&#xff0c;即8个二进制位按…

OJ Prime Gap

目录 1.题目 2.中文翻译 3.题意 4.代码 5.知识点 range的倒序处理&#xff1a; 1.题目 Prime Gap Description The sequence of n − 1 consecutive composite numbers (positive integers that are not prime and not equal to 1) lying between two successive prime…

软考A计划-2023系统架构师-知识点集锦(3/4)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…