Java垃圾回收【GC】详解

2023-11-07

什么是垃圾

垃圾是内存中没有任何引用指向它,并且没有引用的对象无法使用,所以就可以认为这个对象是垃圾,需要被回收释放其占用的内存空间。

垃圾定位
  • 1、引用计数法(RefrenceCount)
    堆中每个对象实例都有一个引用计数,每当有一个引用指向它,计数器加1,引用失效,计数器减1,当计数器为0时,这个对象就是垃圾。简单高效。
    缺点是:无法解决对象之间相互循环引用的问题。
  • 2、根搜索(Root Seaching)
    GC Roots 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。此算法解决了循环引用的问题。
    在这里插入图片描述
    • 虚拟机栈(栈桢中的本地变量表)中的引用的对象
    • 方法区中的类静态属性引用的对象
    • 方法区中的常量引用的对象
    • 本地方法栈中JNI(Native方法)的引用的对象
常用的垃圾回收算法
  • 1、标记清除(Mark Sweep)在这里插入图片描述
    标记清除从根集合进行两次扫描,首先对存活的对象进行标记,在标记完成后统一回收所有未被标记的对象。
    存活对象比较多的情况下使用,多用于老年代。需要扫描两次,效率比较低,容易产生碎片。

  • 2、拷贝(Copying)
    在这里插入图片描述

    拷贝算法将可用内存按容量划分为大小相等的两块,从根集合进行一次扫描,对存活的对象进行标记,然后移动到复制另外一块内存空间中,然后再把已使用过的内存空间清理掉。
    存活对象比较少的情况下使用,只扫描一次,没有内存碎片,多用于年轻代。造成空间浪费,需要调整对象的引用。

  • 3、标记整理(Mark-Compact)
    在这里插入图片描述
    标记整理,标记过程仍然与“标记-清除”算法一样,首先对存活的对象进行标记,其次不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
    不会产生内存碎片,不会造成空间浪费,多用于老年代。需要扫描两次,需要调整对象的引用,效率比较低。

Heap内存逻辑分区

堆大小 = 新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 指定。
在这里插入图片描述

  • 1、新生代
    Eden + Survivor
    • eden:对象最初创建的区域
    • survivor:eden幸存下来的对象所在的区域。
  • 2、老年代
    主要存放程序中年龄较大和需要占用大量内存空间的对象
MinorGC/Young GC

当Eden区内存不足的时候,虚拟机将进行一次MinorGC。Survivor区内存不足不会触发MinorGC。MinorGC采用复制算法。首先,把Eden和Survivor1区域中存活的对象复制到Survivor2区域,同时把这些对象的年龄+1(默认情况下15岁就直接送到老年代了,晋升老年代的阈值可以通过 -XX:MaxTenuringThreshold 设置);然后,清空Eden和Survivor1中的对象;

MajorGC/FullGC

Major GC 是清理永久代。Full GC 是清理整个堆空间—包括年轻代和永久代。

  • 每次晋升到老年代的对象平均大小>老年代剩余空间;
  • MinorGC后存活的对象超过了老年代剩余空间
  • 堆内存分配很大的对象
  • CMS GC异常:
    promotion failed:MinorGC时,survivor空间放不下,对象只能放入老年代,而老年代也放不下造成;
    concurrent mode failure:GC时,同时有对象要放入老年代,而老年代空间不足造成
JVM常用的垃圾回收器
  • Serial收集器(复制算法): 新生代单线程收集器(stw),标记和清理都是单线程,优点是简单高效;
  • ParNew收集器 (复制算法): 新生代收并行集器(stw),实际上是Serial收集器的多线程 版本,在多核CPU环境下有着比Serial更好的表现;
  • Parallel Scavenge收集器 (复制算法): 新生代并行收集器(stw),追求高吞吐量,高效 利用 CPU。吞吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高 效率的利用CPU时间,尽快完成程序的运算任务,适合后台应用等对交互相应要求不 高的场景;
  • Serial Old收集器 (标记-整理算法): 老年代单线程收集器(stw),Serial收集器的老年 代版本;
  • Parallel Old收集器 (标记-整理算法): 老年代并行收集器(stw),吞吐量优先, Parallel Scavenge收集器的老年代版本;
  • CMS(Concurrent Mark Sweep)收集器(标记-清除算法): 老年代并发收集器,以获取最短回收停顿时间为目标的收集器。(初始标记,并发标记,重新标记,并发清除)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java垃圾回收【GC】详解 的相关文章

  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • 不同帐户上的 Spring Boot、JmsListener 和 SQS 队列

    我正在尝试开发一个 Spring Boot 1 5 应用程序 该应用程序需要侦听来自两个不同 AWS 帐户的 SQS 队列 是否可以使用 JmsListener 注解创建监听器 我已检查权限是否正确 我可以使用 getQueueUrl 获取
  • org.apache.hadoop.security.AccessControlException:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] 问题

    我正在使用 java 客户端通过 Kerberos 身份验证安全访问 HDFS 我尝试打字klist在服务器上 它显示已经存在的有效票证 我收到的异常是客户端无法通过以下方式进行身份验证 TOKEN KERBEROS 帮助将不胜感激 这是一
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • 主板中的Win10/win8.1 WHQL支持是否要开启

    主板中的Win10 win8 1 WHQL支持是否要开启 在新式的电脑主板上会有Windows 10 8 1 WHQL支持开启的选项 这个选项的开启和关闭分别代表什么意义呢 这其实还要从UEFI和Legacy两种不同BIOS的说起 Lega
  • 生命在于折腾——MacOS(Inter)渗透测试环境搭建

    一 前景提要 之前使用的是2022款M2芯片的MacBook Air 13寸 不得不说 是真的续航好 轻薄 刚开始我了解到M芯片的底层是ARM架构 我觉得可以接受 虚拟机用的不多 但在后续的使用过程中 发现卡脖子就是卡脖子 随后换了联想R9
  • Linux内核的全局变量

    全局变量 srctree if KBUILD SRC KBUILD SRC CURDIR objtree CURDIR src srctree obj objtree VPATH srctree if KBUILD EXTMOD KBUIL
  • Blender人物骨骼绑定

    Blender人物骨骼绑定 1 建立骨骼父子关系 某些物体依附到其他物体上并成为它的子物体 可由骨骼按E键直接分裂出子骨骼 2 将骨骼建立和三维模型的父子关系 3 设置反向运动学 正常的正向运动学是FK 也就是父骨骼带动子骨骼 而如果想要实
  • mysql中的group by 和 having使用

    mysql中的group by 和 having 使用 理论 sql中的group by 用法解析 Group By语句从英文的字面意义上理解就是 根据 by 一定的规则进行分组 Group 它的作用是通过一定的规则将一个数据集划分成若干个
  • SDL 使用 framebuffer

    SDL 窗口系统 基于X11或WayLand协议 OpenGL 与硬件无关 通过发命令给GPU完成绘制工作 EGL 与硬件相关 是窗口系统 SDL 和OpenGL媒介 SDL Simple DirectMedia Layer 是一套开放源代
  • SpringBoot统一接口返回

    文章目录 前言 思路 1 定义标识 可以定义一个注解作为标识 2 对Controller或者method打上标识 3 请求时判断是否存在该标识 可以利用拦截器 4 对结果重新写入 前言 前后分离时 我们要定义好统一的接口返回格式 eg co
  • PCL点云处理之泊松曲面重建(一百六十一)

    PCL点云处理之泊松曲面重建 一百六十一 一 算法介绍 二 算法实现 1 代码 2 效果 一 算法介绍 泊松曲面重建基于泊松方程 根据泊松方程使用矩阵迭代求出近似解 采用移动立方体算法提取等值面 对所测数据点集重构出被测物体的模型 泊松方程
  • 【C语言基础】标准库函数strcat的使用

    文章目录 C语言基础 标准库函数strcat的使用 一 功能解释 二 函数原型 三 使用示例 1 使用字符数组作为第一个参数 2 使用指向字符数组的指针作为第一个参数 3 使用字符串常量作为第二个参数 4 使用字符数组作为第二个参数 5 使
  • PyTorch学习笔记(20) ——激活函数

    0 前言 本博客内容翻译自纽约大学数据科学中心在2020发布的 Deep Learning 课程的Activation Functions and Loss Functions部分 废话不多说 下面直接开始吧 1 激活函数 本内容将回顾一些
  • js删除数组中指定元素

    js删除数组中某一项或几项的几种方法 一 删除第一个元素 1 shift 方法用于把数组的第一个元素从其中删除 并返回第一个元素的值 注意 此方法改变数组的长度 提示 移除数组末尾的元素可以使用 pop 方法 let arr 1 2 3 4
  • LEARN C++(Methods)

    Getting the most out of these tutorials As you go through these tutorials we recommend a number of practices to maximize
  • CSS 之实现它们它们和它们

    一 CSS画图形 1 用CSS画三角形 首先 需要把元素的宽度 高度设为0 然后设置边框样式
  • mkdocs 使用说明

    mkdocs 使用说明 安装 pip3 install mkdocs 1 4 2 创建项目 mkdocs new my project cd my project 修改 mkdocs yml site name My Docs site u
  • C#使用Quartz.NET详细讲解

    Quartz NET是一个开源的作业调度框架 是OpenSymphony 的 Quartz API的 NET移植 它用C 写成 可用于winform和asp net应用中 它提供了巨大的灵活性而不牺牲简单性 你能够用它来为执行一个作业而创建
  • PCRE正则表达式

    PCRE正则表达式的定义 用于描述字符排列和匹配模式的一种语法规则 它主要用于字符串的模式分割 匹配 查找及替换操作 PHP中的正则函数 PHP中有两套正则函数 两者功能差不多 分别为 一套是由PCRE Perl Compatible Re
  • 黑盒测试中的等价类和边界值

    黑盒测试时基于程序规格说明书 找出程序不符合格则说明书的地方 也就是我们常说的点点点 在进行黑盒测试时 我们可以利用一下几种方法来写出测试用例 尽量用科学的方法来找出更多的缺陷 等价类划分 等价类划分是一种重要的 常用的黑盒测试方法 不需要
  • js打开新的窗口window_前端必备基础知识:window.location 详解

    作者简介 李中凯 八年多工作经验 前端负责人 擅长JavaScript Vue 掘金文章专栏 KaysonLi 的个人主页 专栏 掘金 前端开发人员对 window location对象应该不陌生 通过它不但可以获取当前页面的地址信息 还可
  • android mtk6732 camera otp 加载流程

    在android的hal层获取属性节点信息值 Get Property char value PROPERTY VALUE MAX 0 property get camcaldrv log value 0 MINT32 dumpEnable
  • Java垃圾回收【GC】详解

    什么是垃圾 垃圾是内存中没有任何引用指向它 并且没有引用的对象无法使用 所以就可以认为这个对象是垃圾 需要被回收释放其占用的内存空间 垃圾定位 1 引用计数法 RefrenceCount 堆中每个对象实例都有一个引用计数 每当有一个引用指向