必知必会jvm垃圾回收——对象搜索算法与回收算法

author author     2023-01-27     353

关键词:

垃圾回收(GC)是JVM的一大杀器,它使程序员可以更高效地专注于程序的开发设计,而不用过多地考虑对象的创建销毁等操作。但是这并不是说程序员不需要了解GC。GC只是Java编程中一项自动化工具,任何一个工具都有它适用的范围,当超出它的范围的时候,可能它将不是那么自动,而是需要人工去了解与适应地适用。

拥有一定工作年限的程序员,在工作期间肯定会经常碰到像内存溢出、内存泄露、高并发的场景。这时候在应对这些问题或场景时,如果对GC不了解,很可能会成为个人的发展瓶颈。

接下来的两文将详细学习下JVM中垃圾回收(GC)的各个知识要点。本文先从GC的算法开始先了解,铺垫好基础,下一篇再详细讲JVM具体的GC实现。

GC对象搜索算法

垃圾回收,第一件事就是要搞清楚哪些东西是垃圾,而后才能对这些垃圾进行回收。

那么有什么办法识别对象是否为无用的垃圾呢?狭义地,怎么判断对象是否没被引用呢?

通常有以下两种算法去识别判断<!--more-->

  • 引用计数算法
    这个算法非常简单。给对象一个计数器,每当这个对象被引用了,计数器值加一;引用失效,则减一。但这个对象计数值为0的时候,证明是无用对象,可以被GC程序回收掉。这种算法比较广泛应用在一些脚本语言上,如FLASH、PYTHON等。
    但是引用计数算法无法解决对象间相互引用的问题。当a对象引用了b对象,b对象也引用了a对象,这样a、b两个对象的计数器值都不会为0,即使这两个对象都被其他对象所引用,最终导致这些对象一直无法被回收。这种情况往往会出现在比较复杂的编程语言中。
    技术分享图片

  • 可达性分析算法
    可达性分析算法(GC roots算法),广泛应用于主流的商用语言。设置一个根节点,从图论角度来看,只要从该节点可达一个对象,证明这个对象是存活的(被引用)。
    技术分享图片

通常地,GC会包含以下区域的对象:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象;

垃圾回收算法

了解完垃圾是怎么找出来后,接下来看看它们是怎么被清除的。以下介绍几种清除的算法。

标记-清除算法(Mark-Sweep)

标记-清除,顾名思义,先标记垃圾,再清除。它是GC最基础的算法,后续很多算法都是基于它上面去改进的。
标记的过程在上面搜索GC对象已经介绍过了。被标记的对象,在统一GC的时候会把标记的对象清除掉。这个算法比较简单,不做过多赘述。

技术分享图片
这个算法有一个很明显的缺点,就是在垃圾回收后会产生大量不连续的碎片空间,导致程序要申请较大的对象时常无法找到合适的内存空间,迫使再次GC。

复制算法

复制算法的存在,正是为了解决内存碎片问题。并且这个算法也是分代算法的基础。

将内存分为大小相等的两块,每次程序只使用其中一块,当GC发生的时候,把存活的对象复制到另外一块内存中,整齐的排列,然后清空原来的那块内存。
技术分享图片
可以看到,这种算法有点新生代转移到老年代的感觉。

缺点:

  1. 把内存可使用的空间减少了一半,造成空间的浪费。
  2. 对象存活数量较多的时候,复制性能比较差

这种缺点,在老年代中,对象存活率比较高的场景下是非常场景间。

标记-整理算法(Mark-Compact)

针对复制算法的两个缺点,在老年代一般会用这种标记-整理算法。

把存活的对象移到内存的一段,然后把剩余的空间全部清空掉。
技术分享图片

分代收集算法---

title: 必知必会JVM垃圾回收——对象搜索算法与回收算法
categories:

  • JVM深入
    tags:
  • JVM
  • GC
    date: 2018-09-27 15:09:36

垃圾回收(GC)是JVM的一大杀器,它使程序员可以更高效地专注于程序的开发设计,而不用过多地考虑对象的创建销毁等操作。但是这并不是说程序员不需要了解GC。GC只是Java编程中一项自动化工具,任何一个工具都有它适用的范围,当超出它的范围的时候,可能它将不是那么自动,而是需要人工去了解与适应地适用。

拥有一定工作年限的程序员,在工作期间肯定会经常碰到像内存溢出、内存泄露、高并发的场景。这时候在应对这些问题或场景时,如果对GC不了解,很可能会成为个人的发展瓶颈。

接下来的两文将详细学习下JVM中垃圾回收(GC)的各个知识要点。本文先从GC的算法开始先了解,铺垫好基础,下一篇再详细讲JVM具体的GC实现。

GC对象搜索算法

垃圾回收,第一件事就是要搞清楚哪些东西是垃圾,而后才能对这些垃圾进行回收。

那么有什么办法识别对象是否为无用的垃圾呢?狭义地,怎么判断对象是否没被引用呢?

通常有以下两种算法去识别判断<!--more-->

  • 引用计数算法
    这个算法非常简单。给对象一个计数器,每当这个对象被引用了,计数器值加一;引用失效,则减一。但这个对象计数值为0的时候,证明是无用对象,可以被GC程序回收掉。这种算法比较广泛应用在一些脚本语言上,如FLASH、PYTHON等。
    但是引用计数算法无法解决对象间相互引用的问题。当a对象引用了b对象,b对象也引用了a对象,这样a、b两个对象的计数器值都不会为0,即使这两个对象都被其他对象所引用,最终导致这些对象一直无法被回收。这种情况往往会出现在比较复杂的编程语言中。
    技术分享图片

  • 可达性分析算法
    可达性分析算法(GC roots算法),广泛应用于主流的商用语言。设置一个根节点,从图论角度来看,只要从该节点可达一个对象,证明这个对象是存活的(被引用)。
    技术分享图片

通常地,GC会包含以下区域的对象:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象;

垃圾回收算法

了解完垃圾是怎么找出来后,接下来看看它们是怎么被清除的。以下介绍几种清除的算法。

标记-清除算法(Mark-Sweep)

标记-清除,顾名思义,先标记垃圾,再清除。它是GC最基础的算法,后续很多算法都是基于它上面去改进的。
标记的过程在上面搜索GC对象已经介绍过了。被标记的对象,在统一GC的时候会把标记的对象清除掉。这个算法比较简单,不做过多赘述。

技术分享图片
这个算法有一个很明显的缺点,就是在垃圾回收后会产生大量不连续的碎片空间,导致程序要申请较大的对象时常无法找到合适的内存空间,迫使再次GC。

复制算法

复制算法的存在,正是为了解决内存碎片问题。并且这个算法也是分代算法的基础。

将内存分为大小相等的两块,每次程序只使用其中一块,当GC发生的时候,把存活的对象复制到另外一块内存中,整齐的排列,然后清空原来的那块内存。
技术分享图片
可以看到,这种算法有点新生代转移到老年代的感觉。

缺点:

  1. 把内存可使用的空间减少了一半,造成空间的浪费。
  2. 对象存活数量较多的时候,复制性能比较差

这种缺点,在老年代中,对象存活率比较高的场景下是非常场景间。

标记-整理算法(Mark-Compact)

针对复制算法的两个缺点,在老年代一般会用这种标记-整理算法。

把存活的对象移到内存的一段,然后把剩余的空间全部清空掉。
技术分享图片

分代收集算法

分代算法并不是一个特定的算法,也没有什么新的内容。而是把内存分成多个区域,一般为新生代、老年代等。然后根据不同区域不同的特点,用不同回收算法去回收垃圾。

例如新生代,对象存活率低,比较适用复制算法。老年代存活率高,比较适用Mark-Compact算法。

目前几乎所有的商业虚拟机都是采用分代收集的。具体不同的收集器在下一文再详细说明。


更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码
技术分享图片
分代算法并不是一个特定的算法,也没有什么新的内容。而是把内存分成多个区域,一般为新生代、老年代等。然后根据不同区域不同的特点,用不同回收算法去回收垃圾。

例如新生代,对象存活率低,比较适用复制算法。老年代存活率高,比较适用Mark-Compact算法。

目前几乎所有的商业虚拟机都是采用分代收集的。具体不同的收集器在下一文再详细说明。


更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码
技术分享图片

jvm03——四种垃圾回收算法

...726https://blog.csdn.net/ChenRui_yz/article/details/883929451|0如何确定垃圾 想要回收垃圾,必须得先知道,哪些对象可以被认定为垃圾。关于垃圾确定方式,主要有两种,分别是引用计数法与可访问性分析法,其原理分别如下:1|1引用计... 查看详情

jvm入门及理解——垃圾回收与算法

一、jvm垃圾回收要做的事情哪些内存需要回收什么时候回收怎么回收二、如何判断对象已经死亡,或者说确定为垃圾引用计数法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1;当引用失效时,计... 查看详情

jvm垃圾回收算法

前言java相较于c、c++语言的优势之一是自带垃圾回收器,程序开发人员不用手动管理内存,内存的分配和释放完全由gc(GarbageCollector)来做,极大地提高了软件开发效率及程序健壮性(手动管理内存容易造成内存泄漏)。凡事皆有... 查看详情

jvm垃圾回收算法与垃圾收集器(代码片段)

垃圾回收算法与垃圾收集器1.垃圾收集算法1.1标记清除算法1.1.1基本概念1.1.1.1`mutator`和`collector`1.1.1.2`mutatorroots`(`mutator`根对象)1.1.1.3可达对象1.1.2垃圾回收过程1.1.2.1标记(mark)1.1.2.2清除(sweep)1.1.2.3整体流程1.1 查看详情

jvm垃圾回收算法

1.判断对象是否已死的两种方法1.1 引用计数法  给对象添加一个引用计数器,如果其他对象引用计数器加一,引用失效计数器减一,当计数器为0的时候,则对象就认为是死亡的状态  优点:实现简单,效率高  缺点:无法解决... 查看详情

jvm垃圾回收算法与垃圾收集器

【JVM】垃圾回收算法与垃圾收集器【JVM】垃圾收集器 查看详情

图解jvm垃圾内存回收算法

图解JVM垃圾内存回收算法这篇文章主要介绍了图解JVM垃圾内存回收算法,由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率,下面博主和大家来一起学习一下吧前言首先,我们要讲的是JVM的垃圾回收机... 查看详情

jvm-垃圾回收算法

目录垃圾回收算法标记-清除算法复制算法标记-整理算法分代收集算法分代回收法详解为什么要分两块Survivor区流程详解垃圾回收算法标记-清除算法复制算法标记-整理算法分代收集算法标记-清除算法算法分为“标记”和“清除... 查看详情

jvm,垃圾回收标记算法

八、垃圾回收标记算法1.对象被判定成垃圾的标准没有被其他对象引用2.判断对象是否为垃圾的算法(1)引用计数法  优点and缺点 (2)可达性分析算法     查看详情

jvm垃圾回收机制

jvm垃圾回收目前都是采用分代回收机制,old代和new代分别采用不同算法。按照基本回收策略分:复制、标记-清除算法、标记-压缩算法复制算法(copying)将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另... 查看详情

jvm垃圾回收算法(最全)

JVM垃圾回收算法(最全) 下面是JVM虚拟机运行时的内存模型: 1.方法区Perm(永久代、非堆)2.虚拟机栈3.本地方法栈(Native方法)4.堆5.程序计数器 1首先的问题是:jvm如何知道那些对象需要回收?目前两种标识算法、... 查看详情

jvm垃圾回收概念和算法

GC中的垃圾:特指存在于内存中、不会再使用的对象。内存泄漏和内存溢出的区别: 内存泄漏:内存空间忘记回收,垃圾对象永远无法被回收 内存溢出:垃圾对象(不满足回收条件)所耗内存持续上升,导致内存溢出。1... 查看详情

jvm垃圾回收篇(垃圾回收算法)(代码片段)

垃圾回收算法1.垃圾回收的两个阶段2.垃圾标记算法之引用计数算法3.垃圾标记算法之可达性分析法4.垃圾清除算法之标记清除算法5.垃圾清除算法之复制算法6.垃圾清除算法之标记压缩算法7.垃圾清除算法总结8.其它收集算法1.分代... 查看详情

jvm垃圾回收算法

在说垃圾回收算法之前,先谈谈JVM怎样确定哪些对象是“垃圾”。1.引用计数器算法:引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,计数器-1,当计数器为0的时候... 查看详情

jvm中的四种垃圾回收算法解析

JVM中的垃圾回收算法JVM中的垃圾JVM中的垃圾定义引用计数法原理分析优点问题可达性分析法原理分析GCRoots对象JVM中的垃圾回收标记清除算法原理分析优点问题标记复制算法原理分析优点问题担保机制标记整理算法原理分析优点... 查看详情

jvm中的四种垃圾回收算法解析

JVM中的垃圾回收算法JVM中的垃圾JVM中的垃圾定义引用计数法原理分析优点问题可达性分析法原理分析GCRoots对象JVM中的垃圾回收标记清除算法原理分析优点问题标记复制算法原理分析优点问题担保机制标记整理算法原理分析优点... 查看详情

jvm垃圾回收算法

1、引用计数算法(ReferenceCountingCollector)  引用计数算法作为一种简单但是效率低下的算法,其主要原理如下:在堆中对每个对象都有一个引用计数器;当对象被引用时,引用计数器加1;当引用对象被置为空或者离开作用域... 查看详情

jvm学习--垃圾回收算法

...回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理。stoptheworld   在介绍垃圾回收算法之前,我们需要先了解一个词“stoptheworld”,stoptheworld会在执行某一个垃... 查看详情