iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么理解Java常见知识点中的垃圾回收机制
  • 839
分享到

怎么理解Java常见知识点中的垃圾回收机制

2023-06-05 03:06:25 839人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关怎么理解Java常见知识点中的垃圾回收机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java堆中存放着大量的Java对象实例,在垃圾收集器回收内存前,第一件事

这篇文章将为大家详细讲解有关怎么理解Java常见知识点中的垃圾回收机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Java堆中存放着大量的Java对象实例,在垃圾收集器回收内存前,第一件事情就是确定哪些对象是“活着的”,哪些是可以回收的。

Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于GC引起。

一. 判断对象是否存活的算法

1. 引用计数算法(基本弃用)

引用计数算法是判断对象是否存活的基本算法:给每个对象添加一个引用计数器,没当一个地方引用它的时候,计数器值加1;当引用失效后,计数器值减1。但是这种方法有一个致命的缺陷,当两个对象相互引用时会导致这两个都无法被回收。

2. 根搜索算法(目前使用中)

在主流的商用语言中(Java、C#…)都是使用根搜索算法来判断对象是否存活。对于程序来说,根对象总是可以访问的。从这些根对象开始,任何可以被触及的对象都被认为是”活着的”的对象。无法触及的对象被认为是垃圾,需要被回收。

Java虚拟机的根对象集合根据实现不同而不同,但是总会包含以下几个方面:

  • 栈(栈帧中的本地变量表)中引用的对象。

  • 方法区中的类静态属性引用的变量。

  • 方法区中的常量引用的变量。

  • 本地方法JNI的引用对象。

区分活动对象和垃圾的两个基本方法是引用计数和根搜索。 引用计数是通过为堆中每个对象保存一个计数来区分活动对象和垃圾。根搜索算法实际上是追踪从根结点开始的引用图。

在主流的商用程序语言(如我们的Java)的主流实现中,都是通过可达性分析算法来判定对象是否存活的。

二. 垃圾收集算法

1. 标记-清除算法

分标记和清除两个阶段:首先标记处所需要回收的对象,在标记完成后统一回收所有被标记的对象。

它有两点不足:一个效率问题,标记和清除过程都效率不高;一个是空间问题,标记清除之后会产生大量不连续的内存碎片(类似于我们电脑的磁盘碎片),空间碎片太多导致需要分配大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾回收动作。

2. 复制算法

为了解决效率问题,出现了“复制”算法,他将可用内存按容量划分为大小相等的两块,每次只需要使用其中一块。当一块内存用完了,将还存活的对象复制到另一块上面,然后再把刚刚用完的内存空间一次清理掉。这样就解决了内存碎片问题,但是代价就是可以用内容就缩小为原来的一半。

3. 标记-整理算法

复制算法在对象存活率较高时就会进行频繁的复制操作,效率将降低。因此又有了标记-整理算法,标记过程同标记-清除算法,但是在后续步骤不是直接对对象进行清理,而是让所有存活的对象都向一侧移动,然后直接清理掉端边界以外的内存。

4. 分代收集法

当前商业虚拟机的GC都是采用分代收集算法

为了增大垃圾收集的效率,所以JVM将堆进行分代,分为不同的部分,一般有三部分,新生代,老年代和永久代(在新的版本中已经将永久代废弃,引入了元空间的概念,永久代使用的是JVM内存而元空间直接使用物理内存):

  • 新生代(对应minor GC):所有新new出来的对象都会最先出现在新生代中,当新生代这部分内存满了之后,就会发起一次垃圾收集事件,这种发生在新生代的垃圾收集称为Minor collections。这种收集通常比较快,因为新生代的大部分对象都是需要回收的,那些暂时无法回收的就会被移动到老年代。

  • 老年代(对应Full GC):老年代用来存储那些存活时间较长的对象。一般来说,我们会给新生代的对象限定一个存活的时间,当达到这个时间还没有被收集的时候就会被移动到老年代中。

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

程序中主动调用System.gc()强制执行的GC为Full GC

大概流程:

内存分区:

年轻代(Young Generation)(Eden,Survivor-s0,Survivor-s1,大小比例默认为8:1:1)

年老代(Old Generation)

永久代(Permanent Generation)。(包含应用的类/方法信息, 以及JRE库的类和方法信息.和垃圾回收基本无关)

新生代中的对象“朝生夕死”,每次GC时都会有大量对象死去,少量存活,使用复制算法。新生代又分为Eden区和Survivor区(Survivor from、Survivor to),大小比例默认为8:1:1。

老年代中的对象因为对象存活率高、没有额外空间进行分配担保,就使用标记-清除或标记-整理算法。

新产生的对象优先进去Eden区,当Eden区满了之后再使用Survivor from,当Survivor from 也满了之后就进行Minor GC(新生代GC),将Eden和Survivor from中存活的对象copy进入Survivor to,然后清空Eden和Survivor from,这个时候原来的Survivor from成了新的Survivor to,原来的Survivor to成了新的Survivor from。复制的时候,如果Survivor to 无法容纳全部存活的对象,则根据老年代的分配担保(类似于银行的贷款担保)将对象copy进去老年代,如果老年代也无法容纳,则进行Full GC(老年代GC)。

  • 大对象直接进入老年代:JVM中有个参数配置-XX:PretenureSizeThreshold,令大于这个设置值的对象直接进入老年代,目的是为了避免在Eden和Survivor区之间发生大量的内存复制。

  • 长期存活的对象进入老年代:JVM给每个对象定义一个对象年龄计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳,将被移入Survivor并且年龄设定为1。每熬过一次Minor GC,年龄就加1,当他的年龄到一定程度(默认为15岁,可以通过XX:MaxTenuringThreshold来设定),就会移入老年代。

  • 但是JVM并不是永远要求年龄必须达到最大年龄才会晋升老年代,如果Survivor 空间中相同年龄(如年龄为x)所有对象大小的总和大于Survivor的一半,年龄大于等于x的所有对象直接进入老年代,无需等到最大年龄要求。

三. 垃圾收集器

垃圾回收算法是方法论,垃圾回收器是实现。

  • Serial收集器:串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。(STW)它是虚拟机运行在client模式下的默认新生代收集器:简单而高效(与其他收集器的单个线程相比,因为没有线程切换的开销等)。

  • ParNew收集器:ParNew收集器其实就是Serial收集器的多线程版本。(STW)是许多运行在Server模式下的JVM中首选的新生代收集器,其中一个很重还要的原因就是除了Serial之外,只有他能和老年代的CMS收集器配合工作。

  • Parallel Scavenge收集器:Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量(就是CPU运行用户代码的时间与CPU总消耗时间的比值,即 吞吐量=运行用户代码的时间/[运行用户代码的时间+垃圾收集时间])。

  • CMS收集器:CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。,停顿时间短,用户体验就好。

基于“标记清除”算法,并发收集、低停顿,运作过程复杂,分4步:

  • 初始标记:仅仅标记GC Roots能直接关联到的对象,速度快,但是需要“Stop The World”

  • 并发标记:就是进行追踪引用链的过程,可以和用户线程并发执行。

  • 重新标记:修正并发标记阶段因用户线程继续运行而导致标记发生变化的那部分对象的标记记录,比初始标记时间长但远比并发标记时间短,需要“Stop The World”

  • 并发清除:清除标记为可以回收对象,可以和用户线程并发执行

由于整个过程耗时最长的并发标记和并发清除都可以和用户线程一起工作,所以总体上来看,CMS收集器的内存回收过程和用户线程是并发执行的。

CSM收集器有3个缺点:

1)对CPU资源非常敏感

并发收集虽然不会暂停用户线程,但因为占用一部分CPU资源,还是会导致应用程序变慢,总吞吐量降低。

CMS的默认收集线程数量是=(CPU数量+3)/4;当CPU数量多于4个,收集线程占用的CPU资源多于25%,对用户程序影响可能较大;不足4个时,影响更大,可能无法接受。

2)无法处理浮动垃圾(在并发清除时,用户线程新产生的垃圾叫浮动垃圾),可能出现”Concurrent Mode Failure”失败。

并发清除时需要预留一定的内存空间,不能像其他收集器在老年代几乎填满再进行收集;如果CMS预留内存空间无法满足程序需要,就会出现一次”Concurrent Mode Failure”失败;这时JVM启用后备预案:临时启用Serail Old收集器,而导致另一次Full GC的产生;

3)产生大量内存碎片:CMS基于”标记-清除”算法,清除后不进行压缩操作产生大量不连续的内存碎片,这样会导致分配大内存对象时,无法找到足够的连续内存,从而需要提前触发另一次Full GC动作。

  • Serial Old收集器:Serial 收集器的老年代版本,单线程,“标记整理”算法,主要是给Client模式下的虚拟机使用。可以作为CMS的后背方案,在CMS发生Concurrent Mode Failure是使用

  • Parallel Old 收集器:Parallel Scavenge的老年代版本,多线程,“标记整理”算法,jdk 1.6才出现。在此之前Parallel Scavenge只能同Serial Old搭配使用,由于Serial Old的性能较差导致Parallel Scavenge的优势发挥不出来,Parallel Old收集器的出现,使“吞吐量优先”收集器终于有了名副其实的组合。在吞吐量和CPU敏感的场合,都可以使用Parallel Scavenge/Parallel Old组合。

  • G1收集器:G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征。G1是面向服务端应用的垃圾收集器。它的使命是未来可以替换掉CMS收集器。

关于怎么理解Java常见知识点中的垃圾回收机制就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 怎么理解Java常见知识点中的垃圾回收机制

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

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

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

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

下载Word文档
猜你喜欢
  • 怎么理解Java常见知识点中的垃圾回收机制
    这篇文章将为大家详细讲解有关怎么理解Java常见知识点中的垃圾回收机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java堆中存放着大量的Java对象实例,在垃圾收集器回收内存前,第一件事...
    99+
    2023-06-05
  • .NET垃圾回收机制知识点总结
    这篇文章主要讲解了“.NET垃圾回收机制知识点总结”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“.NET垃圾回收机制知识点总结”吧! .NET资源分托管资源和非托管资源,对于托管资源,.NE...
    99+
    2023-06-17
  • 怎么理解Java 垃圾回收机制
    怎么理解Java 垃圾回收机制,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。什么是自动垃圾回收自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将...
    99+
    2023-06-05
  • Java垃圾回收机制怎么理解
    这篇文章主要讲解了“Java垃圾回收机制怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java垃圾回收机制怎么理解”吧!Java垃圾回收是一个自动运行的管理程序运行时使用的内存的进程...
    99+
    2023-06-17
  • Java 中的垃圾回收机制详解
    目录介绍重要条款:使对象符合 GC 条件的方法请求JVM运行垃圾收集器的方式定稿总结介绍 在 C/C++ 中,程序员负责对象的创建和销毁。通常程序员会忽略无用对象的销毁。由...
    99+
    2024-04-02
  • JS中的垃圾回收机制怎么理解
    这篇“JS中的垃圾回收机制怎么理解”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JS中的垃圾回收机制怎么理解”文章吧。基本类...
    99+
    2023-07-05
  • JavaScript中的垃圾回收机制怎么理解
    今天小编给大家分享一下JavaScript中的垃圾回收机制怎么理解的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。JavaSc...
    99+
    2023-07-06
  • 怎么理解JavaScript垃圾回收机制
    本篇内容介绍了“怎么理解JavaScript垃圾回收机制”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!机制说明找出不再使用的变量,然后释放它...
    99+
    2023-06-25
  • 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 开发语言
  • JavaScript隐藏机制之垃圾回收知识点有哪些
    这篇文章主要介绍“JavaScript隐藏机制之垃圾回收知识点有哪些”,在日常操作中,相信很多人在JavaScript隐藏机制之垃圾回收知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2024-04-02
  • Java的垃圾回收怎么理解
    这篇“Java的垃圾回收怎么理解”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java的垃圾回收怎么理解”文章吧。在说记忆集...
    99+
    2023-06-29
  • Java垃圾回收机制的原理是什么
    本篇内容主要讲解“Java垃圾回收机制的原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java垃圾回收机制的原理是什么”吧!Java 垃圾回收机制1. 垃圾回收主要关注 Java 堆图...
    99+
    2023-06-15
  • Java垃圾回收机制的示例详解
    目录一、概述二、对象已死?1.引用计数算法2.可达性分析算法3.四种引用4.生存还是死亡?5.回收方法区三、垃圾收集算法1.分代收集理论2.名词解释3.标记-清除算法4.标记-复制算...
    99+
    2024-04-02
  • PHP垃圾回收机制的一些理解
    目录垃圾回收是什么东西? PHP 的垃圾回收算法 垃圾回收对性能的影响 总结 相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中。其实,我们这些开发者...
    99+
    2024-04-02
  • java中的垃圾回收机制以及经典垃圾回收器的详细介绍
    本篇内容介绍了“java中的垃圾回收机制以及经典垃圾回收器的详细介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!判断对象存活方法引用计数法...
    99+
    2023-06-20
  • Java虚拟机中垃圾回收机制的原理是什么
    Java虚拟机中垃圾回收机制的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在Java虚拟机中,对象和数组的内存都是在堆中分配的,垃圾收集器主要回收的...
    99+
    2023-05-31
    虚拟机 垃圾回收机制 java
  • PHP7中的垃圾回收机制与原理讲解
    文章目录 前言PHP垃圾回收实现的原理垃圾回收机制引用计数循环垃圾收集 实现原理 总结 前言 本文已收录于PHP全栈系列专栏:PHP快速入门与实战 在计算机程序中,垃圾回收指的...
    99+
    2023-09-20
    php java jvm PHP垃圾回收
  • 如何理解Java常见知识点中的分派机制
    如何理解Java常见知识点中的分派机制,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在Java中,符合“编译时可知,运行时不可变”这个要求的方法主要是静态方法和私有方法。这...
    99+
    2023-06-05
  • python中的垃圾回收机制怎么实现
    这篇文章主要讲解了“python中的垃圾回收机制怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python中的垃圾回收机制怎么实现”吧!python采用的是引用计数机制为主,标记-清...
    99+
    2023-06-28
  • 怎么理解Python中的垃圾回收
    这篇文章主要介绍“怎么理解Python中的垃圾回收”,在日常操作中,相信很多人在怎么理解Python中的垃圾回收问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解Python中的垃圾回收”的疑惑有所帮助!...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作