iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java中的GC收集器详情
  • 647
分享到

java中的GC收集器详情

2024-04-02 19:04:59 647人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录1、GC(Garbage collection )2、GC算法2.1标记活动对象2.2 删除空闲对象2.3 标记清除(Mark-Sweep)2.4 清除压缩(Mark-Sweep

1、GC(Garbage collection )

程序内存管理分手动和自动。

手动内存管理,需要我们编程的时候显式分配和释放空间,但如果忘记释放,会造成严重的内存泄漏问题。如下:


//申请40MB内存
 int* p = malloc(1024 * 1024 * 10 * sizeof(int));
 //释放内存
 free(p);


显式分配和释放很容易就造成内存泄漏。因此我们希望有一种能自动回收内存的方法,这样就可以消除人为造成的错误。我们将这种自动化称为垃圾收集(简称GC

现代高级编程语言基本上都具备GC功能。

2、GC算法

GC算法按照下面两方面内容设计

  • 标记出所有活动对象(程序正在使用或者叫可达对象);
  • 删除未使用的对象和重新整理空间。

2.1标记活动对象

java gc 通过追踪活动对象进行标记,未被标记的对象为空闲状态。空闲状态对象将会在清理阶段被回收。

GC标记对象是从GcRoots开始,它是一类特殊对象,分以下几种:

  • 当前执行方法中的局部变量和方法参数。
  • 活动Java线程
  • 静态变量由其类引用。不过类本身是可以被垃圾收集,回收时将删除所有引用的静态变量。
  • JNI引用是本机代码作为JNI调用的一部分创建的Java对象。这样创建的对象将被特别对待,因为JVM不知道本机代码是否正在引用它。

标记开始时,GC会遍历内存中的整个对象树,从那些GC Roots开始,然后是从根到其他对象(例如实例字段)的引用。GC访问的每个对象都 标记 为活动对象。

标记结束后,如下图所示,蓝色表示为GCroots仍然在引用的对象,灰色表示为空闲对象等待回收。

标记阶段需要注意两方面:

  • 标记需要暂停应用程序线程,这很好理解如果应用线程一直在运行对象活动状态就会一直变化,GC就无法进行标记。这种情况称为 安全点, 导致 Stop The World暂停简述为(STW)。
  • 暂停的持续时间受活动对象的数量影响,不取决于堆的大小和对象总数 。 因此,增加堆大小不会直接影响标记阶段的持续时间。

2.2 删除空闲对象

GC删除空闲对象的一般分为三类:

  • 清除,
  • 压缩,
  • 复制。

2.3 标记清除(Mark-Sweep)

经历标记阶段后,所有空闲对象占用的空间都可以重新分配新对象了。它会维护一个空闲列表,里面记录的空闲区域的位置和大小。这种方式的缺点很明显一是维护空闲列表增加对象开销,二是空闲区域大小不均匀,可能会遇到分配大对象区域不够存储的情况。

2.4 清除压缩(Mark-Sweep-Compact)

清除压多了一步复制动作弥补标记清除的缺点。它将所有活动对象移动到内存区域的开头。不过该方式的缺点是增加复制动作,也就增加了GC暂停时间。

2.5 标记和复制

标记复制这种方式与上面标记清除压缩相似,区别在于它是将活动对象复制到另外一块新的区域(幸存对象区域)。它的好处在于复制动作可以与标记阶段同时进行,缺点是需要另外一个存储区域,该存储区域应足够大以容纳幸存的对象。

3、JVM GC

在较旧的JVM GC中(串行,并行,CMS)将堆分成三个部分:固定内存大小的年轻代,年老代和永久代。

JVM使用两种GC算法分别对年轻代和年老代对象进行回收。年轻代的进行标记复制操作,年老代回收进行标记清除压缩。

3.1 JVM GC事件

我们把GC清除堆不同区域的触发事件分为以下几种:

  • Minor GC 从年轻代空间回收称为次要GC。
  • Major GC 从年老代空间回收主要GC。
  • Full GC 清理整个堆空间,包括年轻代和年老代。

3.2 Serial GC

串行GC,年轻代进行标记复制,年老代进行标记清除压缩。两个GC都是单线程操作,并且触发STW,停止所有应用线程。多CPU计算机中基本不会使用这个GC收集器。只有在单CPU服务器上使用才有意义。

java -XX:+UseSerialGC

3.3 Parallel GC

并行GC,年轻代进行标记复制,年老代进行标记清除压缩。不管是年轻代还是年老代GC时都会触发STW,停止所有应用线程。与串行GC的区别在于它是使用多个线程运行标记和复制/压缩,多线程可以缩短GC收集时间。

java8默认GC收集器就是 parallel gc。不过因为它在标记清理阶段仍然需要停止应用线程,所以在要求较低延迟的场景下可能变得不那么适用。

可以通过-XX:ParallelGCThreads = NNN指定处理的线程数量 。默认值等于计算机中的内核数。


java -XX:+UseParallelGC #使用并行垃圾收集进行清理
java -XX:+UseParallelOldGC #将并行垃圾回收用于。启用此选项会自动设置-XX:+ UseParallelGC
java -XX:+UseParallelGC -XX:+UseParallelOldGC

3.4 Concurrent Mark and Sweep

并发标记扫描(CMS),年轻代空间执行并行标记复制,年老代空间执行并发标记清除。年轻代GC时触STW,停止所有应用线程,然后多线程并行收集。年老代并发标记清除不需要暂停应用线程。它的意义在于着避免了Parallel GC收集器在年老代GC时的长时间停顿。

默认情况下,此GC方式使用的线程数等于计算机物理内核数的1/4。

java -XX:+UseConcMarkSweepGC

我们看下CMS经历的几个阶段

(1)初始标记,暂停应用线程,标记年老代中的所有对象,这些对象是GC Roots,和年轻代中的某些活动对象引用的。

(2)并发标记,GC与应用程序线程并行运行,从初始标记中的根对象开始,遍历年老代所有活动对象进行标记。

(2)并行预清除,与应用线程同时运行,如果某些引用发生了变更,JVM会将变化的区域标记为脏区域。预清除阶段就是对这些脏区域进行处理,并标记还在存活的对象,然后空闲对象将被清除。预清除可以减少重标阶段的工作量。

(4)并发可中止预清除,该阶段也与应用线程并行,属于优化。增加这个阶段是为了让我们能控制该阶段结束的时间,也是为了减轻重标阶段的工作量。


# 控制参数
-XX:CMSScheduleRemarkEdenSizeThreshold=2M
-XX:CMSScheduleRemarkEdenPenetration=50
-XX:CMSMaxAbortablePrecleanTime=5000(单位为毫秒)


比如在并发预清理之后,如果年轻代占用高于CMSScheduleRemarkEdenSizeThreshold,则开始并发可中止的预清除并继续进行预清除,直到年轻代中达到CMSScheduleRemarkEdenPenetration百分比占用率,之后进入重标阶段。如果经过CMSMaxAbortablePrecleanTime时间仍然未达到要求,则直接进入重标阶段。

(5)重标阶段,触发STW,暂停所用应用线程。从GCroots 开始扫描标记年老代的所有活动对象。CMS会尝试在年轻代尽可能空的时候运行最后的备注阶段。

(6)并行清理,应用线程同时执行。该阶段的目的是删除未使用的对象,并回收它们占用的空间以备将来使用。

(7)并行复位,并发执行阶段,重置CMS算法的内部数据结构,并为下一个周期做好准备。

:如上CMS垃圾收集器进行大量工作为的是在年老代回收时不需要暂停应用线程,以减少暂停时间。但是,它存在一些缺点,其中最明显的是年老代碎片,并且在某些情况下,尤其是在大堆上,暂停持续时间缺乏可预测性。

3.5 G1 –垃圾优先

G1是Java9默认GC收集器。它设计的目标是应用在大内存的多处理器计算机,实现高吞吐量。一般应用堆应该在6GB以上且可预测的暂停时间低于0.5秒。G1作为并发标记扫描收集器(CMS)的替代产品。

G1堆内存与旧GC收集器堆内存管理完全不同。它将堆拆分为多个较小的区域(默认根据堆内存拆分为接近2048份)来存对象。

G1收集器的几个阶段:

(1)初始标记,触发STW,标记出从GC Roots直接访问的所有活动对象。

(2)并发标记,从已标记的对象开始扫描,并从根开始标记所有可访问的对象。这个阶段可以被年轻一代的垃圾收集打断。

(3)重新标记,因为并发标记与应用线程并行,所以可能存在遗漏的更新对象。此阶段触发STW,应用线程暂停,完成活动对象最后的标记。

(4)复制/清理阶段,G1选择“活度”最低的区域,这些区域可以被最快地收集。并发标记完成后将进行[GC pause (mixed)]混合GC,年轻代和年老代同时收集。

下图深绿色和深蓝色为清除压缩之后的区域。

G1中几个重要的参数:


# G1区域的大小。该值为2的幂,范围为1MB至32MB。目标是根据最小Java堆大小具有大约2048个区域。
-XX:G1HeapRegionSize=n

# 所需的最大暂停时间设置目标值。默认值为200毫秒。
-XX:MaxGCPauseMillis=200

# 设置要用作年轻代大小的最小值的堆百分比。默认值为Java堆的5%
-XX:G1NewSizePercent=5

# 设置堆大小的百分比,以用作年轻代大小的最大值。默认值为Java堆的60%。
-XX:G1MaxNewSizePercent=60

# 设置STW工作线程的值。将n的值设置为逻辑处理器的数量。的值与n逻辑处理器的数量相同,最多为8
# 如果逻辑处理器多于八个,则将的值设置为逻辑处理器的n大约5/8。在大多数情况下,这n是可行的,但大型SPARC系统的值可能约为逻辑处理器的5/16。
-XX:ParallelGCThreads=n

# 设置平行标记线的数量。设置n为并行垃圾回收线程数(ParallelGCThreads)的大约1/4 。
-XX:ConcGCThreads=n

# 设置触发标记周期的Java堆占用阈值。默认占用率为整个Java堆的45%。
-XX:InitiatingHeapOccupancyPercent=45

# 设置要包含在混合垃圾收集周期中的旧区域的占用阈值。默认占用率为65%。
-XX:G1MixedGCLiveThresholdPercent=65

# 当可回收百分比小于堆垃圾百分比时,Java HotSpot VM不会启动混合垃圾回收周期。默认值为10%。
-XX:G1HeapWastePercent=10

# 设置标记周期后混合垃圾回收的目标数量,以收集最多包含G1MixedGCLIveThresholdPercent实时数据的旧区域。默认值为8个混合垃圾回收。混合馆藏的目标是在此目标数量之内。
-XX:G1MixedGCCountTarget=8

# 设置在混合垃圾收集周期中要收集的旧区域数的上限。缺省值为Java堆的10%。
-XX:G1OldCSetRegionThresholdPercent=10

# 设置保留内存的百分比以使其保持空闲状态,以减少空间溢出的风险。默认值为10%。当增加或减少百分比时,请确保将总Java堆调整相同的数量。
-XX:G1ReservePercent=10

4、总结

本文记录GC算法基础和Java中的几种GC收集器。

到此这篇关于java中的GC收集器详情的文章就介绍到这了,更多相关java中的GC收集器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: java中的GC收集器详情

本文链接: https://www.lsjlt.com/news/155151.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java中的GC收集器详情
    目录1、GC(Garbage collection )2、GC算法2.1标记活动对象2.2 删除空闲对象2.3 标记清除(Mark-Sweep)2.4 清除压缩(Mark-Sweep...
    99+
    2024-04-02
  • java中GC算法和垃圾收集器怎么使用
    在Java中,GC(垃圾回收)算法和垃圾收集器是自动管理内存的关键组件。以下是关于如何使用GC算法和垃圾收集器的一些基本指南:1. ...
    99+
    2023-08-24
    java
  • Vue 收集表单数据方法详情
    表单收集数据代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset=...
    99+
    2024-04-02
  • Java 流处理之收集器详解
    Java 流(Stream)处理操作完成之后,我们可以收集这个流中的元素,使之汇聚成一个最终结果。这个结果可以是一个对象,也可以是一个集合,甚至可以是一个基本类型数据。 以记录&nb...
    99+
    2024-04-02
  • 图文详解PHP中GC回收机制的利用
    目录前言简单铺垫初识GC小试牛刀总结前言 在前面讲魔术方法时就提到过一个问题,__destruct()无论如何都会被触发,但是前提是必须得完成程序的开始与结束,但是如果程序走了一半,...
    99+
    2024-04-02
  • java中避免集合死链调用详情
    目录1. 前言2. 场景3. 环境3.1 开发环境准备3.2 数据准备3.2.1 Mysql数据库表及数据3.2.2 redis库数据4. 解决方式5.完整代码5.1 Model5....
    99+
    2024-04-02
  • 详解 Java性能优化和JVM GC(垃圾回收机制)
    Java的性能优化,JVM GC(垃圾回收机制)在学习Java GC 之前,我们需要记住一个单词:stop-the-world 。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行...
    99+
    2023-06-02
  • JavaScript中Set集合的方法详情
    目录Set集合概述如何创建并使用 SetAdd()Clear()Delete()Entries()Has()ForEach()Keys() 与 values()SizeSe...
    99+
    2024-04-02
  • Java 中的 File类详情
    目录一、File类简单介绍二、 路径的分类三、 构造方法四、 成员方法一、File类简单介绍 为什么要学习File类呢,他的作用又是什么呢? IO流操作中大部分都是对文件进行...
    99+
    2024-04-02
  • Java中的继承详情
    目录一. 继承1.1 继承的实现1.2 继承的好处和弊端二. 继承中的成员访问特点2.1 继承中变量的访问特点2.2 super2.3 继承中构造方法的访问特点2.4 继承中成员方法...
    99+
    2024-04-02
  • Java中JUC 的 Exchange 交换器详情
    目录前言基础使用总结前言 Exchange(交换器)顾名思义,它是用来实现两个线程间的数据交换的,它诞生于 JDK 1.5, 它有两个核心方法: exchange(V x):等待另一...
    99+
    2024-04-02
  • 怎么在java中使用gc判定可回收对象
    怎么在java中使用gc判定可回收对象?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. ...
    99+
    2023-06-14
  • Java收集的雪花算法代码详解
    package com.java265.other; public class Test { // 因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们...
    99+
    2024-04-02
  • Java中如何使用垃圾收集器
    Java中如何使用垃圾收集器,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java垃圾收集器使用小诀窍,垃圾收集器(Garbage Collector,GC)是现代软件虚拟机技...
    99+
    2023-06-17
  • java性能调优System的gc垃圾回收方法
    目录一、什么是System.gc()?二、谁可以调用System.gc()?三、调用System.gc()有什么弊端?四、哪些场景适合显式调用System.gc()?五、如何检测您的...
    99+
    2024-04-02
  • 详解JVM中的GC调优
    目录那些GC的默认值GC的选择GC的最大线程个数初始化heap size最大的heap size分层编译技术我们到底要什么最大暂停时间吞吐率那些GC的默认值 其实GC或者说JVM的参...
    99+
    2024-04-02
  • GC参考手册二java中垃圾回收原理解析
    内存碎片整理 每次执行清除(sweeping), JVM 都必须保证不可达对象占用的内存能被回收重用。但这(最终)有可能会产生内存碎片(类似于磁盘碎片), 进而引发两个问题: 写入操...
    99+
    2024-04-02
  • Java 中的类和对象详情
    目录1、类的定义2、类中变量的类型3、构造方法4、重载方法5、继承5.1 重写方法6、创建对象7、访问实例变量和方法8、比较对象8.1 使用 == 比较对象8.2 使用 equals...
    99+
    2024-04-02
  • Java选择排序和垃圾回收机制详情
    目录一、垃圾回收机制二、Arrays类三、选择排序法四、总结一、垃圾回收机制 创建对象就会占据内存,如果程序在执行过程中不能再使用某个对象,这个对象是徒耗内存的垃圾。作为程序员不用关...
    99+
    2024-04-02
  • 详解Java 虚拟机(第⑤篇)——垃圾收集
    垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后就会消失,因此不需要对这三个区域进行垃圾回收。一、判断一个对象是否可被回收1. 引用计数算法为对象添加一个引用...
    99+
    2023-06-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作