Java 的七种垃圾收集器

2023-10-27

了解 Java 中的内存管理。

用 C 或 C++ 这样的编程语言写一个应用时,需要编写代码来销毁内存中不再需要的对象。当应用程序扩展得越来越复杂时,未使用对象被忽略释放的可能性就越大。这会导致内存泄露,最终内存耗尽,在某个时刻将没有更多的内存可以分配。结果就是应用程序运行失败并出现 OutOfMemoryError 错误。但在 Java 中, 垃圾收集器Garbage Collection (GC)会在程序执行过程中自动运行,减轻了手动分配内存和可能的内存泄漏的任务。

垃圾收集器并不只有一种,Java 虚拟机(JVM)有七种不同的垃圾收集器,了解每种垃圾收集器的目的和优点是很有用的。

1、Serial 收集器

垃圾收集器的原始实现,使用单线程。当垃圾收集器运行时,会停止应用程序(通常称为“stop the world”事件)。适用于能够承受短暂停顿的应用程序。该垃圾收集器占用内存空间比较小,因此这是嵌入式应用程序的首选垃圾收集器类型。在运行时使用以下命令启用该垃圾收集器:

$ java -XX:+UseSerialGC

2、Parallel 收集器

像 Serial 收集器一样,Parallel 收集器也使用“stop the world”方法。这意味着,当垃圾收集器运行时,应用程序线程会停止。但是不同的是,Parallel 收集器运行时有多个线程执行垃圾收集操作。这种类型的垃圾收集器适用于在多线程和多处理器环境中运行中到大型数据集的应用程序。

这是 JVM 中的默认垃圾收集器,也被称为 吞吐量收集器 。使用该垃圾收集器时可以通过使用各种合适的 JVM 参数进行调优,例如吞吐量、暂停时间、线程数和内存占用。如下:

-XX:ParallelGCThreads=<N>
-XX:MaxGCPauseMillis=<N>
-XX:GCTimeRatio=<N>
-Xmx<N>

Parallel 收集器可以使用该命令显式启用: java -XX:+UseParallelGC 。使用这个命令,指定在新生代中通过多个线程进行垃圾回收,而老年代中的垃圾收集和内存压缩仍使用单个线程完成的。

还有一个版本的的 Parallel 收集器叫做 “Parallel Old GC”,它对新生代和老年代都使用多线程,启用命令如下:

$ java -XX:+UseParallelOldGC

3、Concurrent Mark Sweep(CMS)收集器

Concurrent Mark Sweep(CMS)垃圾收集器与应用程序并行运行。对于新生代和老年代都使用了多线程。在 CMS 垃圾收集器删除无用对象后,不会对存活对象进行内存压缩。该垃圾收集器和应用程序并行运行,会降低应用程序的响应时间,适用于停顿时间较短的应用程序。这个收集器在 Java8 已过时,并在 Java14 中被移除。如果你仍在使用有这个垃圾收集器的 Java 版本,可以使用如下命令启用:

$ java -XX:+UseConcMarkSweepGC

在 CMS 垃圾收集器使用过程中,应用程序将暂停两次。首次暂停发生在标记可直接访问的存活对象时,这个暂停被称为 初始标记 。第二次暂停发生在 CMS 收集器结束时期,来修正在并发标记过程中,应用程序线程在 CMS 垃圾回收完成后更新对象时被遗漏的对象。这就是所谓的 重新标记 。

4、G1 收集器

G1 垃圾收集器旨在替代 GMS。G1 垃圾收集器具备并行、并发以及增量压缩,且暂停时间较短。与 CMS 收集器使用的内存布局不同,G1 收集器将堆内存划分为大小相同的区域,通过多个线程触发全局标记阶段。标记阶段完成后,G1 知道哪个区域可能大部分是空的,并首选该区域作为清除/删除阶段。

在 G1 收集器中,一个对象如果大小超过半个区域容量会被认为是一个“大对象” 。这些对象被放置在老年代中,在一个被称为“humongous region”的区域中。 启用 G1 收集器的命令如下:

$ java -XX:+UseG1GC

5、Epsilon 收集器

该垃圾收集器是在 Java11 中引入的,是一个 no-op (无操作)收集器。它不做任何实际的内存回收,只负责管理内存分配。Epsilon 只在当你知道应用程序的确切内存占用情况并且不需要垃圾回收时使用。启用命令如下:

$ java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

6、Shenandoah 收集器

Shenandoah 是在 JDK12 中引入的,是一种 CPU 密集型垃圾收集器。它会进行内存压缩,立即删除无用对象并释放操作系统的空间。所有的这一切与应用程序线程并行发生。启用命令如下:

$ java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

7、ZGC 收集器

ZGC 为低延迟需要和大量堆空间使用而设计,允许当垃圾回收器运行时 Java 应用程序继续运行。ZGC 收集器在 JDK11 引入,在 JDK12 改进。在 JDK15,ZGC 和 Shenandoah 都被移出了实验阶段。启用 ZGC 收集器使用如下命令:

$ java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC

灵活的垃圾收集器

Java 为我们提供了灵活的内存管理方式,熟悉不同的可用方法有助于为正在开发或运行的应用程序选择最合适的内存管理方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 的七种垃圾收集器 的相关文章

  • SLF4J - Logback:如何在运行时配置记录器?

    我们在项目中使用 LogBack 我想根据一些数据库值配置记录器 即如果某个数据库值设置为 true 则记录器应同时使用文件和数据库附加程序 如果为 false 则记录器必须仅使用数据库附加程序 我还想保留使用静态最终记录器 因此我不会在每
  • Spring与AspectJ编译时编织导致:java.lang.VerifyError:非法使用非虚拟函数调用

    我正在尝试使用 Spring 的 AspectJ 编译时编织而不是
  • 在 Windows 7 中,不从命令行强制终止 JVM

    我在 JVM 中运行了 Cobertura 仪器化 jar 当我在运行应用程序的 Windows 控制台中按 Ctrl C 时 JVM 结束并Cobertura 结果已成功刷新到 cobertura ser 文件 但我需要使用命令 工具 不
  • 在 Java 中将系统属性设置为 Null

    在我的单元测试中 我需要将 workingDir 系统属性设置为 Null 但我不能这样做 因为它给了我 NullPointerException System setProperty workingDir null 我该怎么做 您不能将属
  • android-透明RelativeLayout

    我想要制作一个具有可绘制渐变作为背景的活动 并将在其背景顶部显示 4 个面板 相对布局 现在我想让 4 个面板透明 例如 50 以便也可以看到渐变背景 我搜索了谷歌 但我发现只能通过活动而不是布局来做到这一点 如何做我想做的事 您可以创建一
  • spring boot框架下如何过滤tomcat产生的访问日志

    我们使用spring boot框架 通过嵌入式tomcat生成访问日志 访问日志的格式如下 server tomcat access log enabled true server tomcat access log pattern h l
  • 使用 Java NIO 直接访问 Windows 磁盘

    我正在使用一个使用 Java NIO 的库来直接将文件映射到内存 但我在直接读取磁盘时遇到问题 I can直接使用读取磁盘FileInputStream与 UNC 合作 例如 File disk new File PhysicalDrive
  • Spring Batch 多线程

    我正在编写一个 Spring Batch 并希望在需要时对其进行扩展 我的 ApplicationContext 看起来像这样 Configuration EnableBatchProcessing EnableTransactionMan
  • Hibernate HQL 查询:如何将集合设置为查询的命名参数?

    给定以下 HQL 查询 FROM Foo WHERE Id id AND Bar IN barList I set id使用查询对象的setInteger 方法 我想设置 barList用一个List对象 但查看 Hibernate 文档和
  • 指定自定义应用程序上下文

    我们正在将一些数据服务从使用 jersey spring 的 Jersey 1 x 迁移到使用 jersey spring3 的 Jersey 2 x 我们有一些继承自 JerseyTest 的测试类 其中一些类使用 web xml 文件中
  • Maven:缺少工件 org.springframework:spring:jar:4.2.6

    我在 SpringToolSuite 中有一个动态 Web 项目 它被转换为 Maven 项目 我遇到问题 缺少工件 org springframework spring jar 4 2 6 我已经尝试清理 重建和运行该项目 它给 读取文件
  • 摆动刷新周期

    我试图了解何时使用重新验证 重绘 打包 令人惊讶的是 我没有找到详细的底层文档 请随意链接 到目前为止我已经明白这都是 RepaintManager 的责任 油漆 重新油漆指的是脏 干净的东西 pack validate revalidat
  • 在 jFrame 中启用右键单击

    嘿 我正在寻找如何使用 NetBeans 在 jFrame 中启用 仅且仅 右键单击并显示弹出菜单 使用我的代码 private void formMouseClicked java awt event MouseEvent evt pop
  • 如何告诉 Java SAX 解析器忽略无效字符引用?

    当尝试使用字符引用解析不正确的 XML 时 例如 x1 Java 的 SAX 解析器因致命错误而惨死 例如 org xml sax SAXParseException Character reference x1 is an invalid
  • 如何在 apache poi 中找到包含图片的单元格

    我尝试在 xls 文档中循环图像 我写下一个代码 HSSFPatriarch patriarch sheet getDrawingPatriarch if patriarch null Loop through the objects fo
  • 使用JPanel绘制直线并获取点坐标

    我现在完全不知所措 我没有太多用 Java 构建 GUI 我一直在阅读有关 swing 和 JPanel 的所有内容 我认为我想做的事情是可能的 我只是还没有弄清楚how 我正在尝试构建一个 GUI 您可以在其中在某个绘图区域内绘制直线 我
  • 使用 colt java lib 时出现“矩阵太大”异常

    我正在使用 cern colt matrix lib 进行稀疏矩阵计算 但似乎我一直遇到此错误 线程 main 中的异常 java lang IllegalArgumentException 矩阵太大 我认为这是因为构造函数在 nrows
  • 在 Java Jersey 2 JAX-RS 中初始化单例

    我是泽西岛 2 22 2 的新手 请耐心等待 我正在创建一个与 LDAP 服务器交互的 REST 服务 用于存储 删除和检索用户数据 该服务通过执行加密 解密充当安全中介 在使用 REST 服务之前必须进行相当多的初始化 并且我只想执行此初
  • bean 中的 Spring JavaConfig 属性未设置?

    我正在考虑将 Spring JavaConfig 与一些属性文件一起使用 但 bean 中的属性未设置 bean 中的属性未设置 这是我的网络配置 Configuration EnableWebMvc PropertySource valu
  • 使用反射 API 填充 Proto 中的地图字段

    我正在尝试编写一个模块 该模块将获取 Message Builder 和从字段名称到值的映射 并将用值填充构建器 一切正常 直到我遇到地图字段 使用 Proto3 我收到一条特定消息 我知道我可以执行该消息的字段 builder b put

随机推荐

  • centos 6.8 es安装

    配置操作系统参数 1 切换到root用户修改配置sysctl conf vi etc sysctl conf 添加下面配置 vm max map count 655360 1并执行命令 sysctl p 配置es参数 bootstrap m
  • C++ 数组

    C 支持数组数据结构 它可以存储一个固定大小的相同类型元素的顺序集合 数组是用来存储一系列数据 但它往往被认为是一系列相同类型的变量 数组的声明并不是声明一个个单独的变量 比如 number0 number1 number99 而是声明一个
  • STM32CubeIDE 集成的cube MX配置寄存器,IDE入门上手

    1 STM32CubeIDE属于一站式工具 本文带你体验它的强大 strongerHuang的博客 CSDN博客 STM32CubeIDE是一个多功能的集成开发工具 集成了TrueSTUDIO和STM32CubeMX 它是STM32Cube
  • ZYNQ QFLASH MX25L256 调试笔记

    该QFlash是32MB的 而ZYNQ的控制器是16MB的 所以想使用后半部分时 必须要使用4byte地址模式或者扩展模式 先调试扩展模式 在QFlash手册里面有一个写扩展模式命令 C5 写命令的时候 然后再读扩展模式寄存器 C8 就可以
  • Java项目:博客系统西瓜社区(springboot+mybatis-plus+thymeleaf)

    西瓜社区文档 项目全部源码百度网盘地址在文档中 仔细阅读就可发现 前端 社区目前基于开源的markdown框架editorme进行开发的问答和博客的两个功能 后端 springboot mybatis plus swagger2 thyme
  • 记Springboot项目中@Service(或@Component)注解失效的问题解决方法

    一 问题描述 今天基于SpringBoot写好的一个项目程序 启动时 报如下错误 2020 04 07 14 04 41 420 WARN o s b w s c AnnotationConfigServletWebServerApplic
  • 预测数值型数据:回归

    本文传送机 用线性回归找到最佳拟合直线 局部加权线性回归 通过缩减系数来 理解 数据 岭回归 lasso 前向逐步回归 用线性回归找到最佳拟合直线 线性回归 优点 结果易于理解 计算上不复杂 缺点 对非线性的数据拟合不好 适用数据类型 数值
  • 使用WIFI连接新大陆云平台(基于RT_Thread操作系统)

    前言 使用RT Thread Studio 连接WIFI 首先我们需要配置WIFI 具体的配置参考上面这篇文章 下面将会讲述使用WIFI连接到新大陆云平台 相关的AT指令 1 设置WIFI为Station模式 AT CWMODE 1 2 重
  • 拜托!别再问我hashmap是否线程安全

    拜托 别再问我hashmap是否线程安全 一 糟糕的面试 面试官 小王 你说说HashMap的是线程安全的吗 小王 HashMap不安全 在多线程下 会出现线程安全问题 他兄弟HashTable 线程是安全的 但是出于性能考虑 我们往往会选
  • 刷脸支付商家更有针对性地与目标群体互动

    现在我们外出买东西付款 已经有了非常便捷的扫码支付功能 这个功能不仅是年轻人喜欢使用 就连中老年人也跟上的时代的步伐 许多超市 便利店已经菜市场 都能够看到二维码的身影 但是随着时代不断地进步 扫码付款这一新兴方式 接二连三地被曝出许多风险
  • 文本分类流程及可能遇到的问题

    文本分类整体流程及可能遇到的问题 文本分类是一个常见的任务 垃圾邮件分类 评论情感极性分析 舆情分析 新闻分类等等 在网上随便搜索都会出现满屏的解决方案和已有模型 在工作或学习中 接到一个分类任务 可能我们就直接套用已有的模型 方法开始尝试
  • VMWare 虚拟机Ubuntu 22-04系统无法联网,右上角网络图标消失,ifconfig无法获取网络ip

    今天2022年09月18日 一个悲伤的日子 一个大家不能忘记的日子 为了国家强盛 今天周日过来加个班 今天 在Ubuntu linux虚拟机中配置了一些东西 结果把网络搞没了 右上角图标也没了 搜了许多文章 又是重启网络的 重启网络报错 u
  • 智能工厂中,MES管理系统数据采集的方式有哪些

    在工业领域 制造企业的数字化转型正在如火如荼地进行 智能和工业互联网的应用也在加速推进 在这个过程中 工控系统软硬件发挥着关键作用 工控系统涵盖了可编程逻辑控制器 PLC 数据采集与监控系统 SCADA 和分布式控制系统 DCS PLC通常
  • Python 缓存库

    文章目录 缓存库 缓存库的类型 Python中有用的缓存库 Python中的Redis缓存库 Python中的lru cache库 Python中的其他缓存库 总结 缓存是一种可以存储数据以供快速访问的内存类型 它是一个小而快速的内存 用于
  • 图的邻接矩阵

    邻接矩阵 是表示顶点之间相邻关系的矩阵 设G V E 是一个图 其中V v1 v2 vn G的邻接矩阵是一个具有下列性质的n阶方阵 对无向图而言 邻接矩阵一定是对称的 而且主对角线一定为零 在此仅讨论无向简单图 副对角线不一定为0 有向图则
  • Python中enumerate用法详解

    enumerate的意思即为枚举 列举 一句话来说 enumerate的作用就是对可迭代的数据进行标号并将其里面的数据和标号一并打印出来 看一下enumerate的函数 描述 enumerate 函数用于将一个可遍历的数据对象 如列表 元组
  • ElasticSearch Python Client ReadTimeout

    ElasticSearch Python Client ReadTimeout ElasticSearch Python Client API Bulk操作时 当ElasticSearch服务端的性能不足时 Client可能会超时 打印类似
  • 链表—C语言链表中数据域是结构体该如何操作

    链表是数据结构中的首先接触到的 常规的链表数据域为int型 如果链表中数据域是一个结构体该如何操作呢 首先看一个例子 定义一个学生结构体 然后用单向链表保存学生信息 由scanf输入学生信息后形成链表 再打印出所有学生信息 include
  • shell编程之if判断

    目录 一 格式 1 格式1 2 格式2 3 格式3 二 注意 三 例子 1 判断两个数是否相等 2 判断两个数中的最大值 一 格式 1 格式1 if 判断条件 then 判断为true执行的代码 fi 2 格式2 if 判断条件 then
  • Java 的七种垃圾收集器

    了解 Java 中的内存管理 用 C 或 C 这样的编程语言写一个应用时 需要编写代码来销毁内存中不再需要的对象 当应用程序扩展得越来越复杂时 未使用对象被忽略释放的可能性就越大 这会导致内存泄露 最终内存耗尽 在某个时刻将没有更多的内存可