8.GC基本原理

目录

  • 概述
  • 垃圾回收
    • 引用计数法 (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;// 有时候会返回 nullObject 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;// 有时候会返回 nullObject 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.hqwc.cn/news/176348.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# +.Net检验科信息管理系统源码 LIS系统源码

检验科信息管理系统&#xff08;LIS&#xff09; LIS系统集申请、采样、核收、计费、检验、审核、发布、质控、查询、耗材控制等检验科工作为一体的网络管理系统。它的开发和应用将加快检验科管理的统一化、网络化、标准化的进程。 主要包括以下功能&#xff1a; 1、数据采集…

面试:容器技术

目录 为什么需要 DevOpsDocker 是什么&#xff1f;Docker 与虚拟机有何不同&#xff1f;什么是 Docker 镜像&#xff1f;什么是 Docker 容器&#xff1f;Docker 容器有几种状态&#xff1f;解释一下 Dockerfile 的 ONBUILD 指令&#xff1f;什么是 Docker Swarm&#xff1f;如何…

基于Springboot的影城管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的影城管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 项目介绍…

.net core中前端vue HTML5 History 刷新页面404问题

放到启动的应用程序的最后面 app.Run(async (context) > {context.Response.ContentType "text/html";await context.Response.SendFileAsync(Path.Combine(env.WebRootPath, "index.html")); });https://blog.csdn.net/lee576/article/details/88355…

GB/T 1032-2023 三相异步电机试验方法 笔记

仅仅是为了技术分享。如有侵权请随时告知&#xff0c;我会尽快删除相关内容&#xff0c;谢谢&#xff01; 1.阻值的温度效应 7.x 2.温升与负载电 7.x 3.力矩修正公式及功率公式 8.3 3.1铁损和铜损测量 4.空载特性曲线 9.3 4.1 空载损耗 5.堵转特性 6.剩余损耗 6.1 另一种由转子…

Android图片压缩插件

今天才发现这个还有插件&#xff0c;平时都是传网站上压缩完了又下载下来覆盖原文件。现在有这个了&#xff0c;开发好高效&#x1f601;&#xff01;分享给大家&#xff0c;可能对你们有用哈哈&#x1f606;。也可能你们早都知道了……

Excel中使用数据验证、OFFSET实现自动更新式下拉选项

在excel工作簿中&#xff0c;有两个Sheet工作表。 Sheet1&#xff1a; Sheet2&#xff08;数据源表&#xff09;&#xff1a; 要实现Sheet1中的“班级”内容&#xff0c;从数据源Sheet2中获取并形成下拉选项&#xff0c;且Sheet2中“班级”内容更新后&#xff0c;Sheet1中“班…

智能AI系统ChatGPT网站源码+支持OpenAI DALL-E3文生图+支持ai绘画(Midjourney)/支持GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

【计算机网络】VLAN原理和配置

目录 1、VLAN的原理 1.1、什么是VLAN 1.2、为什么要使用VLAN 1.3、VLAN的三种端口类型 1.4、VLAN的划分方法 2、VLAN的配置 1、VLAN的原理 1.1、什么是VLAN VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上…

轻松找回您的珍贵回忆的最好的 6 种照片数据恢复软件!

照片是珍惜过去珍贵时刻的唯一方式。它们让记忆永存&#xff0c;帮助我们重温生命中最美好的时刻。但是&#xff0c;当这些时刻丢失时会发生什么&#xff1f;您是否曾经因系统崩溃而意外删除或丢失照片&#xff1f;丢失照片可能令人心碎&#xff0c;但仍有希望&#xff0c;因为…

UE4动作游戏实例RPG Action解析四:装备系统

导语: 以加血道具为例,详细分析拆解ActionRPG的装备系统,包含装备系统需求和数据结构设计,以及实现 一、装备系统需求: 装备槽: 已获取装备和未获取装备: 当已经装备一个道具时,再次捡到道具,会把道具放在装备库,不会放在装备槽中, 当没有装备道具时,会拾取道具…

牛客网:OR36 链表的回文结构

一、题目 函数原型&#xff1a; bool chkPalindrome(ListNode* A) 二、思路 判断一个单链表是否为回文结构&#xff0c;由于单链表不能倒序遍历&#xff0c;所以需要找到单链表的后半段&#xff0c;并将其逆置&#xff0c;再与前半段链表进行比较。 如何找到单链表的后半段呢&a…