广告
返回顶部
首页 > 资讯 > 后端开发 > Python >JVM中的GC初识
  • 108
分享到

JVM中的GC初识

2024-04-02 19:04:59 108人浏览 薄情痞子

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

摘要

目录GC简介何为GC为何要学习GCGC垃圾对象判定引用计数法可达性分析法常见GC算法分析标记清除标记复制标记整理分代回收章节面试分析GC简介 何为GC GC(Garbage Coll

GC简介

何为GC

GC(Garbage Collection)称之为垃圾回收,是对内存中的垃圾对象,采用一定的算法进行内存回收的一个动作。比方说,java中的垃圾回收会对内存中的对象进行遍历,对存活的对象进行标记,其未标记对象可认为是垃圾对象,然后基于特定算法进行回收。

为何要学习GC

深入理解GC的工作机制,可以帮你写出更好的Java应用,提高开发效率,同时也是进军大规模应用开发的一个前提。

GC垃圾对象判定

引用计数法

这个算法是给每一个对象设置一个引用计数器,每当有一个地方引用这个对象的时候,计数器就加 1,与之相反,每当引用失效的时候就减 1。也就是以计数来判断对象是否为垃圾。当某个对象的引用计数器的值为0时,表示这个对象不会在被实用,JVM中的GC被触发时,可回收这个对象。如图所示:

其中:

  • 绿色云朵是内存中的根对象,表示程序中正在使用的对象。
  • 蓝色圆圈是内存中的活动对象,其中的数字表示其引用计数。
  • 灰色圆圈是内存中没有活动对象引用的对象,表示非活动对象。

对于引用计数法,实现简单,垃圾对应也便于识别。但也有一些缺陷,我们每个对象都需要有一个单独的对象引用计数器,这个计数器的值还要经常更新,还有就是有一个最严重的循环引用问题,如图所示:

其中红色对象实际上是应用程序不使用的垃圾。但由于引用计数的限制,仍然存在内存泄漏。当然也有一些办法来应来对这种情况, 例如 “弱引用”(‘weak’ references)或者使用其它的算法来排查循环引用等。

可达性分析法

这个算法的核心思路就是通过一系列的“GC Roots”对象作为起始点,从这些对象开始往下搜索,搜索所经过的路径称之为“引用链”。当一个对象到 GC Roots 没有任何引用链相连的时候,证明此对象是可以被回收的。否则,证明这个对象有用,不是垃圾。如图所示:

在GC遍历(traverses)内存中整体的对象关系图(object graph)时,首先要确定根对象,那什么样的对象可作为根对象呢?GC规范中指出根对象可以是:

1)Java 虚拟机栈中的引用对象;
2)本地方法栈中 JNI(既一般说的 Native 方法)引用的对象;
3)方法区中类静态常量的引用对象;
4)方法区中常量的引用对象。

当确定了根对象以后,进而从根对象开始进行依赖查找,所有可访问到的对象都认为是存活对象,然后进行标记(mark)。

说明:标记可达对象需要暂停所有应用线程, 以确定对象的引用关系。其暂停的时间, 与堆内存大小、对象的总数没有直接关系, 而是由存活对象(alive objects)的数量来决定。

常见GC算法分析

标记清除

标记清除(Mark-Sweep)算法分为“标记”和“清除”阶段,它首先会标记出内存中所有不需要回收的对象,然后从内存中清除所有未标记的对象。 如图所示:

标记清除算法的的优点是简单直接,缺点是效率低,并且可能会产生大量不连续的碎片。说它效率低是因为标记和清除两个过程都需要扫描内存空间(第一次:标记存活对象,第二次:清除没有标记的对象)。还有就是,清除后产生的大量不连续的内存碎片空间,无法满足较大对象的存储需求,这样就可能会再次触发垃圾回收。所以此垃圾回收算法,应该适合对象存活率较高的的内存区域(比方说JVM中的老年代)。

标记复制

标记复制(Mark-Copy)算法是将内存分为大小相同的两块,当这一块使用完了,就把当前存活的对象复制到另一块,然后一次性清空当前区块。如图所示:

“标记-复制”算法的缺点显而易见,就是内存空间利用率低,适用于那些对象生命周期短、回收频率高的内存区域(比方说JVM中的年轻代)。

标记整理

标记整理清除(Mark-Sweep-Compact)算法结合了“标记-清除”和“复制”两个算法的优点。第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把存活对象“压缩”复制到堆的其中一块空间中,按顺序排放。第三阶段清理掉存活边界以外的全部内存空间。如图所示:

系统GC时每次执行清除(sweeping)操作, JVM 都必须保证“不可达对象“占用的内存能被回收然后重用。内存是被回收了,但这有可能会产生大量的内存碎片(类似于磁盘碎片), 进而引发两个问题:

  • 对象创建时,执行写入操作越来越耗时, 因为寻找一块足够大的空闲内存会变得更加麻烦。
  • 对象创建时, JVM需要在连续的内存块中为对象分配内存。如果碎片问题很严重, 直至没有空闲片段能存放新创建的对象,就会发生内存分配错误(allocation error)。

为了解决碎片问题,JVM在启动GC执行垃圾收集的过程中, 不仅仅是标记和清除, 还需要执行 “内存碎片整理”。这个过程会让所有可达对象(reachable objects)进行依次移动,进而可以消除(或减少)内存碎片,并为新对象提供更大并且连续的内存空间。

标记整理算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题,由于需要向一侧移动等一系列操作,其效率相对低一些,但对内存空间管理上十分优异。适用于那些生命周期长、回收频率低,但注重回收一次内存空间得到足够释放的场景。

分代回收

我们知道垃圾收集要停止整个应用程序的运行,那么假如这个收集过程需要的时间很长,就会对应用程序产生很大性能问题,如何解决这个问题呢?通过实验发现内存中的对象通常可以将其分为两大类:

  • 存活时间较短(这样的对象比较多)。
  • 存活时间较长(这样的对象比较少)。

基于对如上问题的分析,科学家提出了分代回收思路,将VM中内存分为年轻代(Young Generation)和老年代(Old Generation-老年代有时候也称为年老区(Tenured)。例如:

Young区存储的就是那些生命周期短,使用一两次就不再使用的对象,回收一次基本上该区域十之有八的对象全部被回收清理掉,因此Young区采用的垃圾回收算法也就是“标记-复制”算法。Old区存储的是那些生命周期长,经过多次回收后仍然存活的对象,就把它们放到Old区中,Old区一般不去判断这些对象的可达性,直到Old区不够用为止,再进行一次统一的回收,释放出足够的连续的内存空间。所以我们选择“标记-清除”或“标记-整理”算法进行垃圾收集。

在分代回收过程中,垃圾收集事件(Garbage Collection events)通常分为:

  • Minor GC (小型GC):年轻代GC事件,(新对象)分配频率越高, Minor GC 的频率就越高。
  • Major GC (大型GC): 老年代GC事件。
  • Full GC (完全GC):整个堆的GC事件。

说明:一般情况下可以将Major GC与Full GC看成是同一种GC。

章节面试分析

1)何为GC?
2)为什么要GC?
3)如何判定内存中的对象是否为垃圾对象?
4)常用垃圾回收算法有哪些?

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

--结束END--

本文标题: JVM中的GC初识

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

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

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

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

下载Word文档
猜你喜欢
  • JVM中的GC初识
    目录GC简介何为GC为何要学习GCGC垃圾对象判定引用计数法可达性分析法常见GC算法分析标记清除标记复制标记整理分代回收章节面试分析GC简介 何为GC GC(Garbage Coll...
    99+
    2022-11-13
  • JVM中的GC知识点有哪些
    这篇文章主要介绍了JVM中的GC知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JVM中的GC知识点有哪些文章都会有所收获,下面我们一起来看看吧。GC简介何为GCGC(Garbage Collecti...
    99+
    2023-06-30
  • 详解JVM中的GC调优
    目录那些GC的默认值GC的选择GC的最大线程个数初始化heap size最大的heap size分层编译技术我们到底要什么最大暂停时间吞吐率那些GC的默认值 其实GC或者说JVM的参...
    99+
    2022-11-12
  • 初步认识JVM的体系结构
    什么是JVM? JVM(Java Virtual Machine)是一个抽象的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域,它负责执行指令,还要管理数据、内存和寄存器...
    99+
    2022-11-12
  • JVM中GC调优的示例分析
    小编给大家分享一下JVM中GC调优的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!那些GC的默认值其实GC或者说JVM的参数非常非常的多,有控制内存使用的:有控制JIT的:有控制分代比例的,也有控制GC并发的:当然...
    99+
    2023-06-15
  • JVM中四种GC算法案例详解
    目录介绍引用计数算法(Reference counting)算法思想:核心思想:优点:缺点:例子如图:标记–清除算法(Mark-Sweep)算法思想:优点缺点例子如图标记–整理算法算...
    99+
    2022-11-12
  • 解读Jvm的内存结构与GC及jvm参数调优
    目录一、JVM 内存结构1、类加载子系统2、方法区(method)3、堆(heap)4、栈(stack)5、本地方法栈6、pc寄存器(了解即可)7、执行引擎8、垃圾收集器二、堆&nd...
    99+
    2023-05-19
    Jvm内存结构 jvm参数调优 Jvm的内存结构与GC
  • JVM的GC日志记录实例分析
    本文小编为大家详细介绍“JVM的GC日志记录实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“JVM的GC日志记录实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Java应用的GC评估可能大多数程序员...
    99+
    2023-06-29
  • java基础之JVM中GC算法怎么用
    这篇文章主要介绍了java基础之JVM中GC算法怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。JVM内存组成结构:(1)堆所有通过new创建的对象都是在堆中分配内存,其...
    99+
    2023-05-30
    java jvm gc
  • JVM的四种GC算法分别是什么
    本篇文章给大家分享的是有关JVM的四种GC算法分别是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内...
    99+
    2023-06-02
  • 你知道JVM中GC Root对象有哪些吗
    目录JVM中GC Root对象有哪些(一)虚拟机栈中引用的对象(二)方法区中类静态属性引用的对象(三)方法区中常量引用的对象(四)本地方法栈中引用的对象JVM 中的 GC Roots...
    99+
    2023-01-28
    JVM GC Root对象 JVM GC Root JVM对象
  • JVM原理之完整的一次GC流程解读
    目录一、可达性分析算法(GC Roots)二、JVM中的堆结构2.1 为何新生代要分为三个区2.2 新生代对象的分配和回收2.3 老年代对象的分配和回收三、JVM完整的GC流程总结J...
    99+
    2022-12-28
    JVM原理 GC流程 JVM GC流程
  • jstat命令查看jvm的GC情况 (以Linux为例)
     jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 注意!!!:使用的jdk版本是jdk8. ...
    99+
    2023-06-05
  • 初识Oracle的XMLType
    Oracle xmltype是从Oracle 9i开始支持一种新的数据类型,用于存储和管理xml数据,并提供了很多的functions,用来保存、检索和操作xml文档和管理节点。XMLType是系统定义的类...
    99+
    2022-10-18
  • day21 01 包的初识
      day21 01包的初识          包:把解决一类问题的模块放在同一个文件夹里面-----包(一个包里面通常会含有_init_.py文件(python2里面必须有),但是后面的就没有要求一定要有了)        同样导入的时...
    99+
    2023-01-31
  • python 函数的初识
    01 内容大纲 函数的初识 函数的结构与调用 函数的返回值 函数的参数 02 具体内容 函数的初识 写一个获取字符串总个数的代码,不能用len(): s1 = 'fjkdsfjdssudafurpojurojregreupto...
    99+
    2023-01-31
    函数 python
  • 初识JavaScript的基础
    目录一、JavaScript的书写位置二、JavaScript常用的输入输出语句1.浏览器弹出警告框:2.浏览器控制台打印输出信息:3.浏览器弹出输入框,让用户可以输入:三、变量1....
    99+
    2022-11-12
  • 初识python的numpy模块
    目录一、array类型1.1array类型的基本使用1.2对更高维度数据的处理1.3Numpy创建特殊类型的array类型1.3.1生成全为0或全为1的array1.3.2np.ar...
    99+
    2022-11-11
  • JVM中加载、链接、初始化的示例分析
    这篇文章主要为大家展示了“JVM中加载、链接、初始化的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JVM中加载、链接、初始化的示例分析”这篇文章吧。基本概念:类加载的过程大致分为三个阶...
    99+
    2023-05-31
    jvm
  • 一文带你初识java中的String类
    目录什么是字符串字符串常见的赋值方法直接赋值法构造方法进行创建字符串的比较相等字符串常量池字符串常量池的实例字符串的不可变字符串的常见操作字符串的比较字符串的查找字符串替换字符串拆分...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作