引言

上一篇文章 JVM 基本介绍 我们了解了一些基本的 JVM 知识,本篇开始逐步学习垃圾回收,我们都知道既然叫垃圾回收,那回收的就应该是垃圾,可是我们怎么知道哪些对象是垃圾呢? 哪些对象需要被回收? 什么时候需要回收呢?

判断算法

引用计数算法

给每个对象设置一个计数器,每当该对象被引用时引用计数器加 1,有引用断开时引用计数减 1。当引用计数为 0 时表示该对象可以被回收。

这个可以用数据算法中的图形表示,对象 A-对象 B-对象 C 都有引用,所以不会被回收,对象 B 由于没有被引用,没有路径可以达到对象 B,对象 B 的引用计数就就是 0,对象 B 就会被回收。

优点

客观地说,引用计数算法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,也有一些比较著名的应用案例,例如微软公司的 COM(Component Object Model)技术、使用 ActionScript 3 的 FlashPlayer、Python 语言和在游戏脚本领域被广泛应用的 Squirrel 中都使用了引用计数算法进行内存管理。

缺点

主流的 Java 虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。因为相互引用,计数器值永远也不会成为 0 ,所以永远达不到被 GC 回收的条件。

例如下图:对象A,对象B 循环引用,没有其他的对象引用A和B,则A和B 都不会被回收。

可达性分析算法

该算法的原理是:以 GC Roots 的对象作为起始点,然后以该节点为基准开始向下搜索,搜索过程中搜索路径我们称之为引用链,当一个对象到 GC Roots 没有任何引用链连接的时候,说明该对象是不可用的。

注意:我们在 上边的所说的引用都是指定的强引用关系。

因为我们知道 Java 中存在四种引用对象,根据引用强度(从上至下依次减弱)可依次划分为:

  • 强引用 Strong Reference
  • 软引用 Weak Reference
  • 弱引用 Phantom Reference
  • 虚引用 Soft Reference

详细的概念大家下去可以自行查看,此处不再赘述。

可以用作 GC Roots 的对象
  • 方法区 : 类静态变量引用的对象
  • 方法区 : 常量引用的对象
  • 虚拟机栈 : 本地变量表中引用的对象
  • 本地方法栈 : JNI (带 Native 关键字)引用的对象

如下图,对象 D 和根对象之间毫无引用链,则会被回收。

由于这种算法即使存在互相引用的对象,但如果这两个对象无法访问到根对象,还是会被回收。如下图:对象 C 和对象 D 互相引用,但是由于无法访问根节点,还是会被回收。

不可达是不是就一定会被回收?

答案是不一定。

一个对象在真正被回收之前,需要经历两次标记过程:

第一次标记:

如果对象在进行可达性分析之后发现没有与 GC Roots 相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize() 方法,此时分两种情况:

  • 对象没有覆盖 finalize() 方法

  • finalize() 方法已经被虚拟机调用过

在这两种情况下虚拟机都认为此时没有必要执行垃圾回收。

第二次标记:

在第一次标记判定基础之上,如果判定为有必要执行 finalize() 方法,则虚拟机会把这个对象放置到一个叫做 F-Queue 的队列之中,并在之后用 Finalizer 线程去执行回收。(此处的执行指的是 虚拟机会去触发这个方法,但是并不保证回收成功,也不承诺会等待他运行结束,因为如果有个别对象在 finalize() 方法中执行缓慢甚至发生死循环的时候,有可能会导致 F-Queue 队列中的其他对象发生永久等待,最后导致整个垃圾回收系统崩溃)

总结

  • 引用计数法:简单高效,但是对于相互循环引用的对象无法判断是否应该被回收
  • 可达性分析:目前大多虚拟机厂商采用的垃圾回收算法,通过判断其他对象是否和根节点之间存在引用链来分析是否应该被回收
  • 不可达的对象不一定会立即被回收

02 JVM 从入门到实战 | 什么样的对象需要被 GC的更多相关文章

  1. 03 JVM 从入门到实战 | 简述垃圾回收算法

    引言 之前我们学习了 JVM 基本介绍 以及 什么样的对象需要被 GC ,今天就来学习一下 JVM 在判断出一个对象需要被 GC 会采用何种方式进行 GC.在学习 JVM 如何进行垃圾回收方法时,发现 ...

  2. 01 JVM 从入门到实战 | 什么是 JVM

    什么是 JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算 ...

  3. 15套java架构师、集群、高可用、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...

  4. apollo入门demo实战(二)

    1. apollo入门demo实战(二) 1.1. 下载demo 从下列地址下载官方脚本和官方代码 https://github.com/nobodyiam/apollo-build-scripts ...

  5. 学习Vue 入门到实战——学习笔记

    闲聊: 自从进了现在的公司,小颖就再没怎么接触vue了,最近不太忙,所以想再学习下vue,就看了看vue相关视频,顺便做个笔记嘻嘻. 视频地址:Vue 入门到实战1.Vue 入门到实战2 学习内容: ...

  6. nginx入门与实战 安装 启动 配置nginx Nginx状态信息(status)配置 正向代理 反向代理 nginx语法之location详解

    nginx入门与实战 网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web ...

  7. React.js 入门与实战之开发适配PC端及移动端新闻头条平台课程上线了

    原文发表于我的技术博客 我在慕课网的「React.js 入门与实战之开发适配PC端及移动端新闻头条平台」课程已经上线了,文章中是目前整个课程的大纲,以后此课程还会保持持续更新,此大纲文档也会保持更新, ...

  8. ElasticSearch实战系列六: Logstash快速入门和实战

    前言 本文主要介绍的是ELK日志系统中的Logstash快速入门和实战 ELK介绍 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是 ...

  9. Redis入门到实战

    一.Redis基础 Redis所有的命令都可以去官方网站查看 1.基本命令 keys * 查找所有符合给定模式pattern(正则表达式)的 key .可以进行模糊匹配 del key1,key2,. ...

随机推荐

  1. Pascal Triangle

    Description: Given numRows, generate the first numRows of Pascal's triangle. For example, given numR ...

  2. JS的事件绑定、事件流模型

    .t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.JS事件 (一)JS事件分类 1.鼠标事件:click/dbclick ...

  3. bootstrap-table 列宽问题解决

    <th style="width:120px" data-field="Cel1"><div class="th-inner &qu ...

  4. java 引用数据类型(类)

    我们可以把类的类型为两种: 第一种,Java为我们提供好的类,如Scanner类,Random类等,这些已存在的类中包含了很多的方法与属性,可供我们使用. 第二种,我们自己创建的类,按照类的定义标准, ...

  5. .NET开发设计模式-模板模式

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. codeforces 983B XOR-pyramid

    题意: 定义一个函数f(a): 给出一个数组a,有q个询问,每次询问回答在l到r的区间内,连续子串的f函数的最大值. 思路: 画图,来自codeforces SheepRanger 由此图可知,f(l ...

  7. SSIS 处理 bit 列

    一般的编程语言,例如,C#.Java和R等都有布尔类型,用于表示逻辑真(true)和假(false),SQL Server没有布尔类型,但是,在编程时,可以使用bit 类型来代替,bit类型只有两个有 ...

  8. Mac命令行

    参考:http://www.cnblogs.com/-ios/p/4949923.html 必读 涵盖范围: 这篇文章对刚接触命令行的新手以及具有命令行使用经验的人都有用处.本文致力于做到覆盖面广(尽 ...

  9. Tiny4412MMU内存管理

    MMU是Memory Management Unit的缩写,中文名是内存管理单元,MMU是由ARM芯片中的cp15协处理器管理,它的作用是负责虚拟内存到物理内存的映射 要将虚拟内存映射为物理内存,就要 ...

  10. Yii整合ucenter实现单点登录

    原文:http://www.php2.cc/article-1349-1.html 准备工作 1.下载ucenter源码,并安装好 2.下载ucenter开发源码,根据自己的项目下载对应版本(utf- ...