iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java的垃圾回收机制详解
  • 890
分享到

Java的垃圾回收机制详解

javajvm开发语言 2023-09-13 11:09:31 890人浏览 八月长安
摘要

目录 1、C语言与Java语言垃圾回收区别 2、System.gc() 3、面试题引入Java垃圾回收 3.1 jvm怎么确定哪些对象应该进行回收 3.1.1 引用计数法 3.1.2 可达性分析算法  3.2 jvm会在什么时候进行垃圾回收

目录

1、C语言与Java语言垃圾回收区别

2、System.gc()

3、面试题引入Java垃圾回收

3.1 jvm怎么确定哪些对象应该进行回收

3.1.1 引用计数法

3.1.2 可达性分析算法 

3.2 jvm会在什么时候进行垃圾回收的动作

3.2 jvm到底是怎么回收垃圾对象的

4、垃圾回收算法

4.1 标记-清除算法

4. 2 复制算法

4.3 标记-整理算法

4.4 分代收集算法

4.4.2 老年代( Old Generation 

4.4.3 永久代( Permanent Generation )

5、小结

6、垃圾回收器种类


1、任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新的对象使用。对于对象内存的释放就是垃圾回收机制,也叫做GC,对于java开发者来说gc是一个双刃剑2、我们这里找了两张搞笑图片分别来表示 C 语言的垃圾回收和 java的垃圾回收。3、注意:并不是说谁好谁坏,只是一个调侃图。

C语言垃圾回收 

=========================================================================

Java语言垃圾回收 

  

1、C语言与Java语言垃圾回收区别

  • C的垃圾回收是人工的,工作量大,但是可控性高。
  • Java是自动化的,但是可控性很差,甚至有时会出现内存溢出的情况,内存溢出也就是JVM分配的内存中对象过多,超出了最大可分配内存的大小。

2、System.gc()

     提到java的垃圾回收机制就不得不提一个方法:
     System.gc()用于调用垃圾收集器,在调用时,垃圾收集器将运行以回收未使用的内存空间。它将尝试释放被丢弃对象占用的内存。
  然而System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用。
  所以System.gc()并不能说是完美主动进行了垃圾回收。 

3、面试题引入Java垃圾回收

   作为java程序员还是很有必要了解一下gc,这也是面试过程中经常出现的一道题目。我们从三个角度来理解gc。

  1.  jvm怎么确定哪些对象应该进行回收
  2.  jvm会在什么时候进行垃圾回收的动作
  3.  jvm到底是怎么清除垃圾对象的

3.1 jvm怎么确定哪些对象应该进行回收

    对象是否会被回收的两个经典算法:引用计数法,和可达性分析算法。 

3.1.1 引用计数法

 简单的来说就是判断对象的引用数量。实现方式:给对象共添加一个引用计数器,每当有引用对他进行引用时,计数器的值就加1,当引用失效,也就是不在执行此对象是,他的计数器的值就减1,若某一个对象的计数器的值为0,那么表示这个对象没有人对他进行引用,也就是意味着是一个失效的垃圾对象,就会被gc进行回收。
 但是这种简单的算法在当前的jvm中并没有采用,原因是他并不能解决对象之间循环引用的问题。
 假设有A和B两个对象之间互相引用,也就是说A对象中的一个属性是B,B中的一个属性时A,这种情况下由于他们的相互引用,从而使垃圾回收机制无法识别。

3.1.2 可达性分析算法 

       因为引用计数法的缺点,从而引入了可达性分析算法,通过判断对象的引用链是否可达来决定对象是否可以被回收。可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过一系列的名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连(就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的,然后对此对象进行标记。

      注:注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。

3.2 jvm会在什么时候进行垃圾回收的动作

     在确定了哪些对象可以被回收之后,jvm会在什么时候进行回收?

  1.  会在cpu空闲的时候自动进行回收
  2.  在堆内存存储满了之后
  3.  主动调用System.gc()后尝试进行回收 

3.2 jvm到底是怎么回收垃圾对象的

 如何回收说的也就是垃圾收集的算法。
 垃圾回收算法又有四个:标记-清除算法,复制算法,标记-整理算法,分代收集算法.。当前主流使用的是分代收集。

4、来回收算法

4.1 标记-清除算法

    这是最基础的一种算法,分为两个步骤,第一个步骤就是标记,也就是标记处所有需要回收的对象,标记完成后就进行统一的回收掉哪些带有标记的对象。这种算法优点是简单,缺点是效率问题,还有一个最大的缺点是空间问题,标记清除之后会产生大量不连续的内存碎片,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而造成OOM。过多的内存碎片(需要类似链表数据结构维护),也会导致标记和清除的操作成本高,效率低下,内存空间浪费。  

4. 2 复制算法

       复制算法是将可用内存按容量划分为大小相等的两块空间,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况。只是这种算法的代价是将内存缩小为原来的一半。 

       这种算法高效的原因在于分配内存时只需要将指针后移,不需要维护链表等。但它最大的问题是对内存的浪费,使用率只有 50%。

       但这种算法在一种情况下会很高效:Java 对象的存活时间极短。据 IBM 研究,Java 对象高达 98% 是朝生夕死的,这也意味着每次 GC 可以回收大部分的内存,需要复制的数据量也很小,这样它的执行效率就会很高。

      注意: 复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低。更关键的是,浪费了一半的空间。

       

4.3 标记-整理算法

       标记整理算法与标记清除算法很相似,但最显著的区别是:标记清除算法仅对不存活的对象进行处理,剩余存活对象不做任何处理,造成内存碎片;而标记整理算法不仅对不存活对象进行处理清除,还对剩余的存活对象进行整理,重新整理,因此其不会产生内存碎片。

      简单理解,标记整理法,知识在标记清除的基础上,追加了碎片的散落问题,在清除之后进行了碎片的整理,但副作用是增了了GC的时间。

4.4 分代收集算法

       分代收集算法是一种比较智能的算法,也是现在jvm使用最多的一种算法,他本身其实不是一个新的算法,而是他会在具体的场景自动选择以上三种算法进行垃圾对象回收。

      那么现在的重点就是分代收集算法中说的自动根据具体场景进行选择。这个具体场景到底是什么场景。
     场景其实指的是针对jvm的哪一个区域,1.7之前jvm把内存分为三个区域:新生代,老年代,永久代。

     JVM Heap 分代后的划分一般如下所示,新生代一般会分为 Eden、Survivor0、Survivor1区。老年区。

4.4.1 新生代 

       新生代的目标就是尽可能快速的收集掉那些生命周期短的对象,一般情况下,所有新生成的对象首先都是放在新生代的。

      新生代内存按照 8:1:1 的比例分为一个Eden区和两个Survivor0、Survivor1区

  1. 大部分新生对象在Eden区中生成。
  2. Eden区满,触发 Young GC,进行垃圾回收,此时将Eden区存活对象复制到Survivor0区,然后清空Eden区,为后续新的对象分配内存。
  3. Survivor0区也满了时,则将Eden区Survivor0区存活对象复制到Survivor1区,然后清空Eden区Survivor0区。
  4. 此时Survivor0区是空的,然后交换survivor0区和survior1区的角色(即下次垃圾回收时会扫描Eden区和Survivor1区 ),即保持Survivor0区为空,如此往复。
  5. Survivor01区也不足以存放Eden区Survivor0区的存活对象时,就将存活对象直接存放到老年代。如果老年代也满了,就会触发一次FullGC,即新生代、老年代都进行回收。
  6. 注意新生代发生的GC也叫做MinorGC,MinorGC发生频率比较高,不一定等 Eden区满了才触发。而新生代触发Young GC是当Eden区满了才触发。

4.4.2 老年代( Old Generation )

      老年代存放的都是一些生命周期较长的对象,就像上面所叙述的那样,在新生代中经历了N次垃圾回收后仍然存活的对象就会被放到老年代中。

      此外,老年代的内存也比新生代大很多(大概比例是1:2),当老年代满时会触发Major GC(Full GC),老年代对象存活时间比较长,因此FullGC发生的频率比较低。  

4.4.3 永久代( Permanent Generation )

       永久代主要用于存放静态文件,如Java类、方法等。永久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如使用反射、动态代理、CGLib等bytecode框架时,在这种时候需要设置一个比较大的永久代空间来存放这些运行过程中新增的类。


5、小结

     了解过场景之后再结合分代收集算法得出结论:

  1. 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法。只需要付出少量存活对象的复制成本就可以完成收集。
  2. 老年代中因为对象存活率高、没有额外空间对他进行分配担保,就必须用标记-清除或者标记-整理。

6、垃圾回收器种类

         这些垃圾收集器按照运行原理大概可以分为如下几类:

  1. Serial GC,串行,单线程的收集器,运行 GC 时需要停止所有的用户线程,且只有一个 GC 线程。
  2. Parallel GC,并行,多线程的收集器,是 Serial 的多线程版,运行时也需要停止所有用户线程,但同时运行多个 GC 线程,所以效率高一些
  3. Concurrent GC,并发,多线程收集器,GC 分多阶段执行,部分阶段允许用户线程与 GC 线程同时运行,这也就是并发的意思。

注意:

      在jdk8的时候java废弃了永久代,但是并不意味着我们以上的结论失效,因为java提供了与永久代类似的叫做“元空间”的技术。
      废弃永久代的原因:由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryErroy。
      元空间的本质和永久代类似。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。也就是不局限与jvm可以使用系统的内存。理论上取决于32位/64位系统可虚拟的内存大小。 

来源地址:https://blog.csdn.net/qq_41946216/article/details/131201057

--结束END--

本文标题: Java的垃圾回收机制详解

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

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

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

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

下载Word文档
猜你喜欢
  • Java的垃圾回收机制详解
    目录 1、C语言与Java语言垃圾回收区别 2、System.gc() 3、面试题引入Java垃圾回收 3.1 jvm怎么确定哪些对象应该进行回收 3.1.1 引用计数法 3.1.2 可达性分析算法  3.2 jvm会在什么时候进行垃圾回收...
    99+
    2023-09-13
    java jvm 开发语言
  • java 垃圾回收机制以及经典垃圾回收器详解
    判断对象存活方法 引用计数法:在对象中添加一个引用计数子,每当一个地方引用他时,计数器就加一,当引用失效时,计数器就减一。 会有对象循环引用问题: objA.instance =...
    99+
    2024-04-02
  • Java 中的垃圾回收机制详解
    目录介绍重要条款:使对象符合 GC 条件的方法请求JVM运行垃圾收集器的方式定稿总结介绍 在 C/C++ 中,程序员负责对象的创建和销毁。通常程序员会忽略无用对象的销毁。由...
    99+
    2024-04-02
  • Java垃圾回收机制的示例详解
    目录一、概述二、对象已死?1.引用计数算法2.可达性分析算法3.四种引用4.生存还是死亡?5.回收方法区三、垃圾收集算法1.分代收集理论2.名词解释3.标记-清除算法4.标记-复制算...
    99+
    2024-04-02
  • Python垃圾回收机制详解
    目录1. 引用计数2. 标记-清除3. 分代回收4. 其他4.1 JNI(Java Native Interface)总结 Python 的GC模块主要运用了引用计数来跟踪和回收垃圾...
    99+
    2024-04-02
  • 详解JavaScript的垃圾回收机制
    目录为什么需要垃圾回收(GC)什么是垃圾回收垃圾产生垃圾回收策略引用计数标记循环引用引发的问题解决方法引用计数算法的优缺点标记清除算法核心思想标记清除算法优缺点标记整理算法V8引擎的...
    99+
    2024-04-02
  • Java基础之垃圾回收机制详解
    目录一、GC的作用二、GC主要回收哪些内存三、分代回收四、垃圾回收器五、总结一、GC的作用 进行内存管理 C语言中的内存,申请内存之后需要手动释放;一旦忘记释放,就会发生内存泄漏! ...
    99+
    2024-04-02
  • 浅谈Java垃圾回收机制
    目录一.什么是垃圾二.怎么回收垃圾2.1 静态对象什么时候变成垃圾被回收2.2 新生代和年老代三、垃圾回收算法3.1 标记清除算法3.2 复制清除算法(专门用于处理年轻代垃圾的)3....
    99+
    2024-04-02
  • 垃圾回收机制
      我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(称为垃圾),就应该将其占用的内存给回收掉。变量名是访问到变量的唯一方式,所以当一个变量值没有任何关联的变量名时,我们就无法访问到该变量了,该变量就是...
    99+
    2023-01-30
    机制 垃圾
  • PHP的垃圾回收机制(全网详解)
    概念: PHP的垃圾回收机制是自动的,它通过内置的垃圾回收器(Garbage Collector)来实现。当一个PHP对象不再被引用时,它就成为垃圾。垃圾回收器会定期扫描内存中的所有对象,将没有引用的对象标记为垃圾,并释放它们占用的内存空间...
    99+
    2023-09-01
    php jvm java
  • Go语言垃圾回收机制详解
    Go语言(也称为Golang)是谷歌开发的一种高效的编程语言,具有并发性和垃圾回收机制等特点。本文将详细解释Go语言中的垃圾回收机制,包括其原理、实现方式以及代码示例。 1. 垃圾回收...
    99+
    2024-04-02
  • python垃圾回收机制!
    python的三种垃圾回收机制:1.python采用的是引用计数机制为主;2.标记-清除;为辅的策略3.分代收集(隔代回收、分代回收)为辅的策略 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内...
    99+
    2023-01-31
    机制 垃圾 python
  • Java jvm垃圾回收详解
    目录常见面试题1.JVM内存回收和分配1.1主要的区域?gc测试1.2大对象进入老年代1.3长期存活的对象进入老年代1.4主要进行gc的区域gc的类型Young GcFull Gc1...
    99+
    2024-04-02
  • java中的垃圾回收机制以及经典垃圾回收器的详细介绍
    本篇内容介绍了“java中的垃圾回收机制以及经典垃圾回收器的详细介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!判断对象存活方法引用计数法...
    99+
    2023-06-20
  • Java超详细分析垃圾回收机制
    目录前言垃圾回收概述内存溢出和内存泄漏垃圾回收算法标记阶段STW(Stop-the-World)回收阶段标记-清除算法复制算法标记-压缩算法三种算法的比较总结前言 在前面我们对类加载...
    99+
    2024-04-02
  • PHP垃圾回收机制讲解
    PHP的垃圾回收机制 垃圾回收机制是一种动态存储分配的方案。它会自动释放程序不再需要的已分配的内存块。垃圾回收机制可以让程序员不必过分关心程序内存分配,从而将更多的精力投入到业务逻辑...
    99+
    2024-04-02
  • 怎么理解Java 垃圾回收机制
    怎么理解Java 垃圾回收机制,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。什么是自动垃圾回收自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将...
    99+
    2023-06-05
  • Java垃圾回收机制怎么理解
    这篇文章主要讲解了“Java垃圾回收机制怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java垃圾回收机制怎么理解”吧!Java垃圾回收是一个自动运行的管理程序运行时使用的内存的进程...
    99+
    2023-06-17
  • day09(垃圾回收机制)
    1,复习 文件处理 1.操作文件的三步骤 -- 打开文件:硬盘的空间被操作系统持有 | 文件对象被应用程序持续 -- 操作文件:读写操作 -- 释放文件:释放操作系统对硬盘空间的持有 2.基础的读写 ...
    99+
    2023-01-31
    机制 垃圾
  • GC垃圾回收机制
    GC垃圾回收机制 一、 GC原理:1、为什么进行垃圾回收 二、JVM与回收算法:1、内存分配2、回收算法1、标记-清除(Mark-sweep)2、复制(Copying)3、标记-整理(Ma...
    99+
    2023-09-24
    jvm java 算法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作