• 前言

总所周知,jvm的垃圾收集算法一般包括标记、清除、整理三个阶段,最近在看了有关于垃圾收集的标记算法,记录一下自己的理解。

垃圾收集中标记算法有两种:一种是引用计数法,一种是根搜索算法。

  • 引用记数法

引用计数法非常容易理解,jvm为每一个对象设立一个引用计数器,当该对象被引用时,计数器就加一,引用取消时则减一。

当jvm开始gc时,jvm判断该对象的引用计数器是否为0,若为0则标记为可清除对象。

引用计数器有个致命的缺点是无法解决循环依赖问题,这也导致这个算法被弃用。

如下图所示,当对象A中有对B的引用,对象B中也有对A的引用,两者之间形成循环依赖。

除此之外,还有一个point引用了对象A,此时程序中还有point这个指针能够使程序到达这两个对象,

一旦point引用取消,我们就会丢失对这两个对象的控制,同时引用计数器未到达0,所以对象一直存在在堆中,JVM不能进行回收,从此造成内存泄漏。

  • 根搜索算法

根搜索算法是目前大部分JVM所使用的标记算法。

根搜索算法会以根对象集合中的根对象出发,进行自上往下的搜索,与根对象直接连接或间接连接的对象都可以被搜索。

当JVM无法到达某个对象时,它会被标记为可清除对象。

根对象集合指的是:

  1. JAVA栈中的对象引用
  2. 本地方法栈的对象引用
  3. 运行时常量池中的对象引用
  4. 方法区中的类静态属性的对象引用
  5. 类对应的唯一数据类型的Class对象(这句话有点抽象,实际上每个类都有一个Class对象用于表示这个类在运行时被JVM加载的相关信息,如类名、方法、属性等)

可以使用ClassName.class、实例化对象.class、Class.forName(),获取该类的Class对象

根搜索算法的过程

JVM垃圾收集算法之标记算法的更多相关文章

  1. JVM GC-----3、垃圾标记算法(二)

    在上一篇文章中,介绍了在GC机制中,GC是以什么标准判定对象可以被标记的,以及最有效最常用的可达性分析法.今天介绍另外一种非常常用的标记算法,它的应用面也相当广泛.这就是:引用计数法 Referenc ...

  2. JVM GC-----2、垃圾标记算法(一)

    在上一篇文章中,我介绍了关于GC机制中,GC在确认垃圾对象后,是如何回收这些垃圾对象的几种算法.现在介绍下GC机制一般是如何定位(或者叫做标记)出这些垃圾对象的.我们先来问下自己,如何判介绍了断一个对 ...

  3. JVM垃圾收集算法(标记-清除、复制、标记-整理)

     [JVM垃圾收集算法] 1)标记-清除算法: 标记阶段:先通过根节点,标记所有从根节点开始的对象,未被标记的为垃圾对象(错了吧?) 清除阶段:清除所有未被标记的对象 2)复制算法: 将原有的内存空间 ...

  4. JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法

    标记-清除算法 此垃圾收集算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记对象,它的标记过程前面已经说过——如何判断对象是否存活/死去 死去的对象就会 ...

  5. jvm系列(三):java GC算法 垃圾收集器

    GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计 ...

  6. JVM垃圾收集算法

    JVM垃圾收集 1. 判断对象是否存活 引用计数算法 对象添加一个引用计数器,每个地方引用它,计数器值加+1:当引用失效,计算器值减1:任何时刻计数器为0的对象不可能被使用.引用计数算法实现简单,高效 ...

  7. JVM笔记(三) 垃圾收集器(2)收集算法

    垃圾收集器2:收集算法 主要通过阅读<深入了解Java虚拟机>(周志明 著)和网络资源汇集而成,为本人学习JVM的笔记.同时,本文理论基于JDK 1.7版本,暂不考虑 1.8和1.9 的新 ...

  8. JVM垃圾收集规则和算法

    1.垃圾收集 Garbage Collection 程序计数器.虚拟机栈.本地方法栈这三部分内存随着线程生而生,随着线程灭而自然的回收,他们的大小在编译期间就大致确定了下来,所以对这部分的回收是具备确 ...

  9. JVM垃圾收集策略与算法

    垃圾收集策略与算法 程序计数器.虚拟机栈.本地方法栈随线程而生,也随线程而灭:栈帧随着方法的开始而入栈,随着方法的结束而出栈.这几个区域的内存分配和回收都具有确定性,在这几个区域内不需要过多考虑回收的 ...

随机推荐

  1. kali linux 更换镜像源

    编辑sources.list文件 leafpad /etc/apt/sources.list #aliyun 阿里云 deb http://mirrors.aliyun.com/kali kali-r ...

  2. 构建一个给爬虫使用的代理IP池

    做网络爬虫时,一般对代理IP的需求量比较大.因为在爬取网站信息的过程中,很多网站做了反爬虫策略,可能会对每个IP做频次控制.这样我们在爬取网站时就需要很多代理IP. 代理IP的获取,可以从以下几个途径 ...

  3. QT QWidget 关闭的流程

    当QWidget被点击右上角“X”关闭时: 1.调用虚函数closeEvent 2.调用QWidget的析构函数

  4. SpringMvc通过controller上传文件代码示例

    上传文件这个功能用的比较多,不难,但是每次写都很别扭.记录在此,以备以后copy用. package com.**.**.**.web.api; import io.swagger.annotatio ...

  5. jiagu-工具使用

    比较好的一套处理工具吧,感谢作者,原文地址:https://github.com/ownthink/Jiagu 练习一下使用 """ Funciton: jiagu测试 ...

  6. Angular Material

    Angular Material 的设计之美   Ng-Matero 0.3 已发布,新增 module schematic 以及 page schematic,详见 README 前言 Angula ...

  7. AQS4源码

    @SuppressWarnings("restriction") public abstract class AbstractQueuedSynchronizer1 extends ...

  8. spring 事件使用

    1.事件定义 import lombok.Data; import org.springframework.context.ApplicationEvent; /** * 事件定义,这里监听MsgMe ...

  9. TestNG系列(一)TestNG+Eclipse环境配置

    前提 1.JDK的安装与环境变量的配置 2.Eclipse的下载与安装 以上这些是基础中的基础,不再详细介绍. Eclipse安装TestNG插件 打开eclipse--->help---> ...

  10. Linux中常用命令pipe

    大多数linux命令处理数据后都会输出到标准输出,但是如果数据要经过系列列的步骤处理后,才是需要的数据个数,这种需求就需要管道来帮助完成. 管道命令使用"|"作为界定符,将界定符前 ...