什么是自动垃圾回收?

自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用对象),则没有被任何指针给指向,因此占用的内存也可以被回收掉。

在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存。而 Java 不一样,它有垃圾回收器,释放内存由回收器负责。本文接下来将介绍垃圾回收机制的基本过程。

 

第一步:标记

这个过程的第一步叫做标记。这一阶段,垃圾回收器识别哪些内存正在使用,哪些内存未被使用。

被引用的对象以蓝色展示。未被引用的对象以金黄色展示。在标记阶段,所有对象都需要扫描并做出判断。如果系统中的所有对象都必须扫描到,这将是一个非常耗时的过程。

第二步:清除

这一步会删掉标记出的未引用对象。

内存分配器会保留指向可用内存的引用,以供分配新对象。

压缩

为了提升性能,删除了未引用对象后,还可以将剩下的已引用对象放在一起(压缩),这样就能更简单快捷地分配新对象了。

为什么使用分代垃圾回收?

如前所述,标记并整理所有JVM里的对象,效率是很低的。随着越来越多的对象被分配,对象列表不断增长,导致垃圾回收时间越来越长。然而,根据应用程序的经验分析,大多数的对象都是短命的。

下面是这类数据的一个例子。Y轴表示分配的字节数,X轴表示随着时间分配的字节数。

正如你所看到的,随着时间的推移,仍然存活的对象越来越少。事实上,大多数对象的生命周期都很短,如图左侧较高的值所示。

 

JVM 分代

根据之前的规律,就可以用来提升 JVM 的效率了。方法是,把堆分成几个部分(就是所谓的分代),分别是新生代、老年代,以及永生代。

新对象会被分配在新生代内存。一旦新生代内存满了,就会开始对死掉的对象,进行所谓的小型垃圾回收过程。一片新生代内存里,死掉的越多,回收过程就越快;至于那些还活着的对象,此时就会老化,并最终老到进入老年代内存。

Stop the World 事件 —— 小型垃圾回收属于一种叫 "Stop the World" 的事件。在这种事件发生时,所有的程序线程都要暂停,直到事件完成(比如这里就是完成了所有回收工作)为止。

 

老年代用来保存长时间存活的对象。通常,设置一个阈值,当达到该年龄时,年轻代对象会被移动到老年代。最终老年代也会被回收。这个事件成为 Major GC。

Major GC 也会触发STW(Stop the World)。通常,Major GC会慢很多,因为它涉及到所有存活对象。所以,对于响应性的应用程序,应该尽量避免Major GC。还要注意,Major GC的STW的时长受年老代垃圾回收器类型的影响。

永久代包含JVM用于描述应用程序中类和方法的元数据。永久代是由JVM在运行时根据应用程序使用的类来填充的。此外,Java SE类库和方法也存储在这里。

如果JVM发现某些类不再需要,并且其他类可能需要空间,则这些类可能会被回收。

 
 

分代垃圾回收过程

既然已经了解了为什么将堆分成不同的代,现在就该看看这些空间到底是如何交互的。下面的图片展示了JVM中对象分配和老化的过程。

首先,任何新对象都在Eden区分配。两个survivor区都是空的。

当Eden区满了,触发一次Minor GC。

被引用的对象被移动到第一个Survivor区,未被引用的对象会在Eden区清除时一并删除。

 

在下一次Minor GC中,Eden区也会做同样的操作。删除未被引用的对象,并将被引用的对象移动到Survivor区。然而,这里,他们被移动到了第二个Survivor区(S1)。此外,第一个Survivor区(S0)中,在上一次Minor GC幸存的对象,会增加年龄,并被移动到S1中。待所有幸存对象都被移动到S1后,S0和Eden区都会被清空。注意,Survivor区中有了不同年龄的对象。

在下一次Minor GC中,会重复同样的操作。不过,这一次Survivor区会交换。被引用的对象移动到S0,。幸存的对象增加年龄。Eden区和S1被清空。

 
 

此幻灯片演示了 promotion。 在较小的GC之后,当老化的物体达到一定的年龄阈值(在该示例中为8)时,它们从年轻一代晋升到老一代。

随着较小的GC持续发生,物体将继续被推广到老一代空间。

所以这几乎涵盖了年轻一代的整个过程。 最终,将主要对老一代进行GC,清理并最终压缩该空间。

 

Java 垃圾回收机制 (分代垃圾回收ZGC)的更多相关文章

  1. JVM | 分代垃圾回收策略的基本概念以及过程

    一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对 ...

  2. Android内存管理(11)*常见JVM回收机制「Java进程内存堆分代,JVM分代回收内存,三种垃圾回收器」

    参考: http://www.blogjava.net/rosen/archive/2010/05/21/321575.html 1,Java进程内存堆分代: 典型的JVM根据generation(代 ...

  3. JVM调优-Java垃圾回收之分代回收

    为什么要进行分代回收? JVM使用分代回收测试,是因为:不同的对象,生命周期是不一样的.因此不同生命周期的对象采用不同的收集方式. 可以提高垃圾回收的效率. Java程序运行过程中,会产生大量的对象, ...

  4. Java中的分代垃圾回收策略

    一.分代GC的理论基础 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大 ...

  5. java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)

    为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象, ...

  6. 【java虚拟机】分代垃圾回收策略的基础概念

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6602166.html 一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一 ...

  7. JVM堆内存控制/分代垃圾回收

    JVM的堆的内存, 是通过下面面两个参数控制的 -Xms 最小堆的大小, 也就是当你的虚拟机启动后, 就会分配这么大的堆内存给你 -Xmx 是最大堆的大小 当最小堆占满后,会尝试进行GC,如果GC之后 ...

  8. JVM分代垃圾回收策略的基础概念

    由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中有分代这一策略.本文介绍了分代策略的目标,如何分代,以及垃圾回收的触发因素. 文章总结了JVM垃圾回收策略为什么要分代,如何分代,以及垃圾回收 ...

  9. JVM调优总结(六)-分代垃圾回收详述2

    分代垃圾回收流程示意 选择合适的垃圾收集算法 串行收集器 用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高.但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器.当然,此收集器 ...

随机推荐

  1. DB Link 去除域名

    1.查看global_name的设置 SQL> show parameters global_name; NAME                                 TYPE    ...

  2. SCUT - 254 - 欧洲爆破 - 概率dp - 状压dp

    https://scut.online/p/254 思路很清晰,写起来很恶心. #include<bits/stdc++.h> using namespace std; #define l ...

  3. 洛谷 - P1004 - 方格取数 - 简单dp

    https://www.luogu.org/problemnew/show/P1004 这道题分类到简单dp但是感觉一点都不简单……这种做两次的dp真的不是很懂怎么写.假如是贪心做两次,感觉又不能证明 ...

  4. hdoj5792 【树状数组】【未完待续】

    题意: 求有多少种四个数满足Aa < Ab,Ac > Ad,1 < =a < b < = n ,1 < = c < d < = n ; 思路: 只要找到 ...

  5. 11.6NOIP模拟赛

    [数据规模和限制] 对于全部测试数据,满足 N,M,K≤,W≤ 各个测试点的数据规模及特殊性质如下表. 测试点 N M K ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ 师 更多咨询:北京信息学窦老师 QQ ...

  6. Oracle更新数据为MD5加密数据

    业务场景:在做安全等保问题,需要将原来保存的用户明文密码改成md5加密的密文密码,数据库是Oracle的 首先Oracle要管理员账号登录才可以调md5函数,具体函数是DBMS_OBFUSCATION ...

  7. vim normal 模式下L键

    vim normal 模式下L键总是到一行的最后一个字符,而不是最后一个字符的下一个字符,这样进入插入模式,就还得往右移动一下,就很费劲? 怎么解决 更新: a键进入插入即可

  8. 富文本编辑器vue2-editor实现全屏功能

    vue2-editor非常不错,可惜并未带全屏功能,自己实现了一个,供大家参考. 实现思路:自定义模块. 1. 定义全屏模块Fullscreen /** * 编辑器的全屏实现 */ import no ...

  9. 题解报告:hihoCoder #1050 : 树中的最长路

    描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已. 但 ...

  10. 7.1 Java集合概述

    List 有序.重复的集合 Set 无序.不可重复的集合 Map 具有映射关系的集合 jdk1.5之后.Java增加了Queue体系集合,代表一种队列集合实现