8.GC基本原理

news2024/11/19 16:30:27

目录

  • 概述
  • 垃圾回收
    • 引用计数法 (Reference Counting)
    • 根可达分析算法 (GCRooting Tracing)
    • 对象引用类型
      • 强引用
      • 软引用
      • 弱引用
  • 清除垃圾
    • 1.标记-清除算法 (Mark-Sweep)
    • 2.复制算法 (Copying)
    • 3.标记-整理算法 (Mark-Compact)
    • 分代回收 (Generational Collection)
  • 垃圾回收器
    • GC-串行收集器
      • Serial与SerialOld
    • 并行收集器
      • Parallel Scavenge (Stop)
      • Parallel Old
      • ParNew
      • CMS
      • Garbage-First (G1)
        • G1内存划分
      • ZGC
  • 结束

概述

相关文章在此总结如下:

文章地址
jvm基本知识地址
jvm类加载系统地址
双亲委派模型与打破双亲委派地址
运行时数据区地址
运行时数据区-字符串常量池、程序计数器、直接内存地址
jvm中对象创建流程与内存分配地址
jvm对象内存布局地址

垃圾回收

垃圾回收是必须的,不然 jvm 内存很快就会满。
没有被引用的对象,称之为垃圾对象

垃圾对象查找方式

  • 引用计数法 (Reference Counting)
  • 根可达分析算法 (GCRooting Tracing)

引用计数法 (Reference Counting)

当对象引用消失,对象就称为垃圾

堆内存中主要存在三种引用关系:

  • 单一引用
  • 循环引用
  • 无引用
    在这里插入图片描述
    由上图可知,引用计数法,是无法发现 循环引用 这种情况的,易发生内存泄露问题。性能也是有问题的,要全部遍历一次,这是这种计数法的缺陷。

根可达分析算法 (GCRooting Tracing)

通过 GCRoots作为对象起点向下搜索,当一个对象到 GCRoots 没有任何引用链时此对象是垃圾
在这里插入图片描述

引用链 (ReferenceChain) : GCRoots 搜索走过的路径

垃圾对象死亡前至少经历两次标记:

  • 第一次:可达性分析,没有引用链对象会被第一次标记
  • 第二次:标记后的对象会经历筛选,如果筛选不通过,则会被第二次标记

对象引用类型

对象引用有哪些?

jdk 1.2之后,java对象的引用进行了扩充:强引用软引用、弱引用、虚引用

引用类型被垃圾回收时间用途生存时间
强引用从来不会对象的一般状态jvm停止时终止
软引用内存不足时对象缓存内存不足时终止
弱引用正常GC对象缓存GC后终止
虚引用正常GC类似事件回调机制GC后终止
无引用正常GC对象的一般状态GC后终止

强引用

代码中普遍的存在,只要强引用还在,就不会被GC。

Object obj = new Object();

软引用

非必须引用,内存溢出之前进行回收,如内存还不够,才会抛出异常。

package com.fun.info;

import java.lang.ref.SoftReference;

public class Reference {
    public static void main(String[] args) {
        Object obj = new Object();
        SoftReference<Object> sf = new SoftReference<>(obj);
        obj = null;
        // 有时候会返回 null
        Object o = sf.get();
        System.out.println("o==" + o);
    }
}

应用场景:软引用可用来实现内存敏感的高速缓存。
例如:

应用需要读取大量本地文件,如果每次读取都从硬盘读取会严重影响性能,如果一次性全部加载到内存,内存可能会溢出
可以使用软引用解决这个问题,使用一个HashMap来保存文件路径和文件对象管理的软引用之间的映射关系。
内存不足时,jvm会自动回收缓存文件对象的占用空间,有效避免 OOM 问题

HashMap<String, SoftReference<InputStream>> fileCache = new HashMap<>();

弱引用

非必须引用,只要有GC,就会被回收。

 Object o1 = new Object();
 WeakReference<Object> wf = new WeakReference<>(o1);
 o1 = null;
 // 有时候会返回 null
 Object o2 = wf.get();
 // 返回是否被垃圾回收器标记为即将回收的垃圾
 boolean enqueued = wf.isEnqueued();
 System.out.println("o1 = " + o2);
 System.out.println("enqueued =" + enqueued);
  • 虚引用是每次垃圾回收的时候都会被回收,通过虚引用的get方法永远获取到的数据为null,因此也被称为幽灵引用
  • 作用:跟踪对象被垃圾回收的状态,仅仅是提供一种确保对象被回收后,做某些事情的机制。类似监听机制。
  • ThreadLocalThreadLocalMap 就是用了弱引用。

清除垃圾

1.标记-清除算法 (Mark-Sweep)

  • 分为 标记清除 两个阶段:
    • 标记:标记出所有需要回收对象
    • 清除:统一回收掉所有对象
  • 缺点:
    • 执行效率不稳定
    • 空间碎片:会产生大量不连续内存碎片

2.复制算法 (Copying)

  • 内存分为两块,清除垃圾时,将存活对象复制到另一块
  • S0和S1区就是基于这个算法诞生的
  • Eden:S = 8:2
  • 不用担心S区不够,由Old做内存担保
  • 优缺点:
    • 优点:没有内存空间碎片化
    • 缺点:存在空间浪费

3.标记-整理算法 (Mark-Compact)

  • 标记:标记出所有需要回收对象
  • 清除:统一回收掉所有对象
  • 整理:将所有存活对象向一端移动
  • 优缺点:
    • 优点:空间没有浪费,没有内存碎片化问题
    • 缺点:性能较低

分代回收 (Generational Collection)

  • 新生代:选择 复制算法弱分代假说
  • 老年代:选择 标记-清除标记-整理,强分代假说

垃圾回收器

有 8 种不同的垃圾回收器,它们分别用于不同分代的垃圾回收

新生代 (复制算法) : Serial 、ParNew 、Parallel Scavenge
老年代 (标记-清除、标记-整理):SerialOld、Parallel Old、CMS
整堆:G1、ZGC

GC-串行收集器

Serial与SerialOld

配置参数:-XX:+UseSerialGC
特点:

  • Serial新生代收集器,单线程执行,使用复制算法
  • SerialOld老年代收集器,单线程执行,使用标记-整理算法
  • 进行垃圾收集时,必须暂停用户线程

SafePoint
垃圾回收时,是需要暂停用户线程的,如果产生垃圾的速度大于回收的速度,那永远回收不了。
SafePoint线程挂起的点主要有:

  • 循环的末尾
  • 方法返回前
  • 调用方法的call之后
  • 抛出异常的位置

并行收集器

Parallel Scavenge (Stop)

配置参数: -XX:+UseParallelGC
特点:简称 PS

  • 吞吐量优先收集器,垃圾收集需要暂停用户线程
  • 新生代使用并行回收器,采用复制算法
  • 老年代使用串行收集器,采用标记-整理算法

Parallel Old

配置参数: -XX:+UseParallelOldGC
特点:

  • PS收集器的老年代版本
  • 吞吐量优先收集器,垃圾收集需要暂停用户线程,对 CPU 敏感
  • 新生代使用复制算法
  • 老年代使用并行收集器,采用 标记-整理算法

ParNew

配置参数: -XX:+UseParNewGC
配置参数: -XX:ParallelGCThreads=n、垃圾收集线程数
特点:

  • 新生代并行ParNew,老年代串行SerialOld
  • Serial的多线程片
  • 单核CPU不建议使用

CMS

配置参数: -XX:+UseConcMarkSweepGC
特点:

  • 低延时,减少STW(Stop-The-World)对用户的影响
  • 并发收集,用户线程与收集线程一起执行,对CPU资源敏感
  • 不会等待堆填满再收集,到达阀值就开始收集
  • 采用 标记-清除算法 ,所以会产生内存碎片

实际上是精细了标记阶段的流程,降低 STW 来实现低延时

  • 初始标记阶段:会STW,标记出GCRoots可以关联到的对象 ,关联对象较少,所以很快
  • 并发标记阶段:不会STW,遍历GCRoots直接对象的引用链,耗时长
  • 重新标记阶段:会STW,修正并发标记期间的新对象记录
  • 并发清除阶段:不会STW,清除垃圾对象,释放内存空间

Garbage-First (G1)

G1是一款面向服务端应用的全功能垃圾收集器大内存 企业配置的主要是G1。
配置参数: -XX:+UseG1GC
特点

  • 吞吐量和低延时都行的整堆垃圾收集器
  • G1最大堆内存 32M2048 = 64GB,最小堆内存 1M2048=2GB,低于此值不建议使用
  • 全局使用标记-整理算法收集,局部采用复制算法收集
  • 可预测的停顿:能让使用者指定GC消耗时间(超过这个时间,则判断无回收价值,不会回收,即筛选回收),默认是200ms。

详细流程:

  • 初始标记:会STW,标记出GCRoots可以关联到的对象,耗时短
  • 并发标记:不会STW,遍历GCRoots直接对象的引用链,耗时长
  • 最终标记:会STW,修正并发标记期间,标记产生变动的那部分
  • 筛选回收:会STW,对各个Region的回收价值成本排序,根据用户期望GC停顿时间确定回收计划
G1内存划分

在这里插入图片描述
**取消新生代与老年代的物理划分:**采用若干个固定大小的Region

Region区类型(逻辑上):

  • Eden区
  • Survivor
  • Old
  • Humongous 当对象的容量超过了Region的50%,则被认为是巨型对象
# 使用G1垃圾收集器
-XX:+UseG1GC
# 设置期望达到的最大GC停顿时间指标(jvm会尽力实现,但不保证达到),默认值是 200 毫秒
-XX:MaxGCPauseMillis=
# 设置的 G1 区域的大小。值是 2 的幂,范围是 1MB 到 32MB 之间
# 目标是根据最小的 java 堆大小划分出约 2048 个区域
# 默认是堆内存的 1/2000
-XX:G1HeapRegionSize=n
# 设置并行垃圾回收线程数,一般将n的值设置为逻辑处理器的数量,建议最多为8.
-XX:ParallelGCThreads=n
# 设置并行标记的线程数。将n设置为ParallelGCThreads的1/4左右。
-XX:ConcGCThreads=n
# 设置触发标记周期的 java 堆占用率阀值。默认占用率是整个 java 堆的 45%
-XX:InitiatingHeapOccupancyPercent=n

ZGC

ZGC (Z Garbage Collector) 在 jdk11 中引入 的一种可扩展的低延迟垃圾收集器,在jdk15中发布稳定版本

配置参数: -XX:+UseZGC
特点:

  • <1ms最大暂停时间(jdk16是10ms,jdk16+是<1ms),不会随着堆内存增加而增加
  • 适合内存8MB,16TB
  • 并发,基于Region、压缩、NUMA感知、使用色彩指针、使用负载屏障
  • 垃圾收集算法:标记-整理算法
  • 主要目标:低延时

相关参数:

# 启用ZGC
-XX:+UseZGC
# 设置最大堆内存
-Xmx
# 打印 GC 日志
-Xlog:gc
# 打印 GC 详细日志
-Xlog:gc*

结束

至此,GC基本原理就结束了,如有疑问,欢迎评论区留言。

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

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

相关文章

《网络协议》07. 其他协议

title: 《网络协议》07. 其他协议 date: 2022-10-07 18:24:02 updated: 2023-11-15 08:00:52 categories: 学习记录&#xff1a;网络协议 excerpt: IPv6、WebSocket、WebService&#xff08;SOAP&#xff0c;WSDL&#xff09;、HTTPDNS、FTP、邮件&#xff08;SMTP&#xff0c;…

上机实验三 图的最小生成树算法设计 西安石油大学数据结构

二叉树设计 实验名称&#xff1a;二叉树设计 &#xff08;1&#xff09;实验目的&#xff1a; 1&#xff09; 掌握二叉树的逻辑结构。 2&#xff09; 掌握二叉树的二叉链表存储结构&#xff1b; 3&#xff09; 掌握基于二叉链表存储的二叉树的遍历等操作的实现。 &#x…

Kibana:使用 “链接” 面板简化 Kibana 仪表板导航 - Links panel

作者&#xff1a;Teresa Alvarez Soler 我们很高兴地宣布 Kibana 仪表板的最新功能版本&#xff1a;链接面板&#xff08;Links panel&#xff09;&#xff0c;这是在仪表板之间组织和导航的简单方法。 此功能在 Kibana 8.11 的技术预览版中提供。 有时你可能希望创建多个主题…

μC/OS-II---计时器管理1(os_tmr.c)

目录 创建一个计时器重新启动一个计时器停止一个计时器删除一个计时器 计时器是倒计时器&#xff0c;当计数器达到零时执行某个动作。用户通过回调函数提供这个动作。回调函数是用户声明的函数&#xff0c;在计时器到期时被调用。在回调函数中绝对不能进行阻塞调用&#xff08;…

SUMO道路封闭车辆绕行仿真实验【TraCI】

本文将介绍如何在 SUMO 交通模拟中动态选择车辆绕行指定道路。 绕道是城市驾驶中的常见现象&#xff0c;造成原因有很多&#xff0c;包括建筑和交通事故等。 无论出于何种原因&#xff0c;并非所有车辆都会选择避开这些道路&#xff1b; 有些人可能会毫不犹豫地直接开车过去&a…

Payshield 10K是什么意思?有什么作用?

PayShield 10K是一种支付安全产品&#xff0c;由数字货币和法币混合而成的数字货币产品。它的意思是保护商家在交易过程中可能遭受的损失。这种产品的主要作用是保护数字货币支付系统的安全&#xff0c;并确保商家在交易过程中获得他们应得的收益。 PayShield 10K具有以下特点和…

基于鸟群算法优化概率神经网络PNN的分类预测 - 附代码

基于鸟群算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于鸟群算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于鸟群优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

Domino为外出Internet邮件设置DKIM签名

大家好&#xff0c;才是真的好。 如果你看了上篇《Domino中和邮件安全有关的SPF、DKIM介绍》内容&#xff0c;想必就对DKIM概念不陌生&#xff0c;当然&#xff0c;上篇我们讲的是邮件入站的SFP、DKIM签名检查&#xff0c;这篇讲述的是外出邮件的DKIM签名。 是的&#xff0c;…

算不上最全,但都是必备——Spring MVC这些不会不行啊

Spring MVC篇 Spring MVC执行流程 四大组件 前端控制器DispatcherServlet处理器映射器HandlerMapping处理器适配器HandlerAdaptor视图解析器ViewResolver 视图阶段&#xff08;JSP&#xff09; 请求先到前端控制器DispatcherServlet DispatcherServlet将根据该请求的路径去…

理解 R-CNN:目标检测的一场革命

一、介绍 对象检测是一项基本的计算机视觉任务&#xff0c;涉及定位和识别图像或视频中的对象。多年来&#xff0c;人们开发了多种方法来应对这一挑战&#xff0c;但基于区域的卷积神经网络&#xff08;R-CNN&#xff09;的发展标志着目标检测领域的重大突破。R-CNN 及其后续变…

深入探讨Linux中的文本文件查看命令

目录 前言1 cat命令2 less命令3 more命令4 head命令5 tail命令6 总结 前言 在Linux系统中&#xff0c;文本文件是日常工作中不可或缺的一部分&#xff0c;无论是配置文件、日志文件还是代码文件&#xff0c;都需要用到文本文件查看命令。在本文中&#xff0c;我们将深入研究一…

【深度学习】吴恩达课程笔记(四)——优化算法

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【吴恩达课程笔记专栏】 【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础 【深度学习】吴恩达课程笔记(二)——浅层神经网络、深层神经网络 【深度学习】吴恩达课程笔记(三)——参数VS超参数、深度…

如何从 iCloud 恢复永久删除的照片?答案在这里!

在数字时代&#xff0c;丢失珍贵的照片可能会令人痛苦。然而&#xff0c;了解如何从 iCloud 恢复永久删除的照片可以带来一线希望。无论是意外删除还是技术故障&#xff0c;本指南都提供了 2023 年的最新方法来找回您的珍贵记忆。发现分步解决方案并轻松重新访问您的照片库。不…

智能供应链中的预测算法:理论与实践

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 引言 智能供应链已经成…

制作属于你的视觉小说,ComfyUI工作流#N3期AIGC训练营

什么是视觉小说&#xff1f; Visual Novel 最初这种形式被称为“有声小说” 视觉小说是一种源自日本的电子游戏类型&#xff0c;它以图像和文本为主要表现形式&#xff0c;通常包含大量的对话和故事情节。 &#xff08;大量对话&#xff09; 在视觉小说中&#xff0c;玩家可以通…

AJAX入门Day01笔记

Day01_Ajax入门 知识点自测 如下对象取值的方式哪个正确? let obj {name: 黑马 }A: obj.a B: obj()a 答案 A选项正确 哪个赋值会让浏览器解析成标签显示? let ul document.querySelector(#ul) let str <span>我是span标签</span>A: ul.innerText str B: ul…

HTML+CSS+JavaScript实战(一个简易的视频播放器)

效果如下&#xff1a; 思路很常规&#xff0c;无需注释即可看懂&#xff08;其实是懒得敲 bushi&#xff09; 没有注释也能跑&#xff0c;so直接上源码~ 感谢 夏柔站长 提供的免费API index.html <!DOCTYPE html> <html lang"en"> <head><meta …

UE4动作游戏实例RPG Action解析三:实现效果,三连击Combo,射线检测,显示血条,火球术

一、三连Combo 实现武器三连击,要求: 1.下一段Combo可以随机选择, 2.在一定的时机才能再次检测输入 3. 等当前片段播放完才播放下一片段 1.1、蒙太奇设置 通过右键-新建蒙太奇片段,在蒙太奇里创建三个片段,并且移除相关连接,这样默认只会播放第一个片段 不同片段播…

一分钟搞懂什么是this指针(未涉及静态成员和函数)

前言 我们在学习类的过程中&#xff0c;一定听说过this指针&#xff0c;但是并不知道它跟谁相似&#xff0c;又有什么用途&#xff0c;所以接下来&#xff0c;让我们一起去学习this指针吧&#xff01; 一、this指针的引入 我们先来看下面两段代码&#xff0c;它们输出的是什么&…

Rust实战教程:构建您的第一个应用

大家好&#xff01;我是lincyang。 今天&#xff0c;我们将一起动手实践&#xff0c;通过构建一个简单的Rust应用来深入理解这门语言。 我们的项目是一个命令行文本文件分析器&#xff0c;它不仅能读取和显示文件内容&#xff0c;还会提供一些基础的文本分析&#xff0c;如计算…