JVM的垃圾回收机制的三个问题

  • 回收哪些数据?
  • 什么回收?
  • 在哪里回收?

本就回答垃圾回收机制是回收哪些数据?

所谓“要回收的垃圾”无非就是那些不可能再被任何途径所使用的对象。无需再使用的对象,会被标记为垃圾,等待JVM回收此部分内存。

可达性分析法基本原理

方法原理:通过一系列称为"GC Roots"的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链(即GC Roots到对象不可达时),则证明此对象是不可用的。

有哪些GCRoots 节点嗯?

  • 虚拟机栈(栈帧中的局部变量区,也叫局部变量表)中引用的对象;
  • 本地方法栈中 JNI(Native方法)引用的对象。
  • 方法区中的类静态变量属性引用的对象
  • 方法区中常量引用的对象

从图中可以看出,A,B,C,D,E,F是可达的,G,H,I,J,K不可达,这个仅仅是一个例子。实际是很复杂的。

虚拟机栈中的引用的对象 :我们在程序中正常创建一个对象,对象会在堆上开辟一块空间,同时会将这块空间的地址作为引用保存到虚拟机栈中,如果对象生命周期结束了,那么引用就会从虚拟机栈中出栈,因此如果在虚拟机栈中有引用,就说明这个对象还是有用的,这种情况是最常见的。

全局的静态的对象:也就是使用了 static 关键字,由于虚拟机栈是线程私有的,所以这种对象的引用会保存在共有的方法区中,显然将方法区中的静态引用作为 GC Roots 是必须的;

常量引用:就是使用了 static final 关键字,由于这种引用初始化之后不会修改,所以方法区常量池里的引用的对象也应该作为 GC Roots;

Native 方法引用对象:这一种是在使用 JNI 技术时,有时候单纯的 Java 代码并不能满足我们的需求,我们可能需要在 Java 中调用 C 或 C++ 的代码,因此会使用 native 方法,JVM 内存中专门有一块本地方法栈,用来保存这些对象的引用,所以本地方法栈中引用的对象也会被作为 GC Roots。(较少)

JVM 四种引用

可达性分析的 GC Roots 均为引用对象,那么引用对象有 4 种引用类型如下:

  • 强引用
  • 软引用
  • 弱引用
  • 虚引用

强引用

定义:强引用就是指在程序代码之中普遍存在的,类似Object obj = new Object()这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。强引用标识着,我们不希望这些对象被回收掉。当内存空间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

public class DemoTest {public static void main(String[] args) {Object obj = new Object(); // 强引用obj = null; //消除强引用}
}

软引用

定义:软引用用来描述一些还有用,但并非必需的对象。对于软引用关联着的对象,如果内存充足,则垃圾回收器不会回收该对象,如果内存不够了,就会回收这些对象的内存。

在 JDK 1.2 之后,提供了 SoftReference 类来实现软引用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用

定义:弱引用描述非必需对象。被弱引用关联的对象只能生存到下一次垃圾回收之前,垃圾收集器工作之后,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。Java 中的类 WeakReference 表示弱引用。

虚引用

定义:"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用在 Java 中使用 java.lang.ref.PhantomReference 类表示。

作用:虚引用主要用来跟踪对象被垃圾回收的活动。

虚引用与软引用和弱引用的区别:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

使用示例:虚引用必须和引用队列(ReferenceQueue)联合使用

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Main {public static void main(String[] args) {ReferenceQueue<String> queue = new ReferenceQueue<String>();PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);System.out.println(pr.get());}
}

JVM 的可达性分析法和四种引用相关推荐

  1. JVM day03 四种引用 垃圾回收

    JVM day03 如何判断对象可以回收 引用计数法 一旦相互持有引用,就导致对象永远没法被回收. jvm并没有采用这种算法. 可达性分析算法 由GC Root出发,开始寻找,看看某个对象是否可达,如 ...

  2. JVM学习笔记之四 四种引用和垃圾回收的两次标记

    四种引用和两次标记 四种引用 java中的数据类型我们知道是分为基本数据类型和引用类型的.基本数据类型是8种,分别是boolean byte short int long double float c ...

  3. JVM的四种引用:强,软,弱,虚(与gc有关)

    JVM的四种引用 强 软 弱 虚 强 gc时不回收 软 软引用对象在gc时,在内存溢出前,会回收; 弱 弱引用对象在gc时,不论内存使用情况都会回收; 虚 虚引用对象在gc后,会发送一条通知给 Ref ...

  4. JVM之引用类型Java四种引用

    Java中提供了一个Reference抽象类,此类定义所有引用对象共有的操作,与垃圾收集器密切配合实现的.主要是为了决定某些对象的生命周期,有利于JVM进行垃圾回收.而继承此类的有四种引用,分别是St ...

  5. 垃圾回收之如何判断对象可以回收、四种引用以及实际案例操作

    垃圾回收 JVM内存结构中的堆存在垃圾回收机制,我们接下来就来详细地学习一下垃圾回收的相关知识. 1. 如何判断对象可以回收 1.1 引用计数法 只要一个对象被其他变量所引用,那就让这个对象的计数+1 ...

  6. JVM:可达性分析算法

    在堆里存放着几乎多有的java对象实例,垃圾搜集器在对堆进行回收之前,第一件事情就是确定这些对象之中哪些还"存活"着(即通过任何途径都无法使用的对象). 一.可达性分析算法 在Ja ...

  7. 可达性分析算法与强弱引用

    可达性算法是判断对象是否能够被GC Root节点链接,来筛选存活对象和死亡对象的一种算法,这里的"链接"指的是Java语言当中的引用:强引用,软引用,弱引用,虚引用. 四种引用: ...

  8. 通过强弱软虚四种引用进一步了解垃圾回收机制

    在Java对象里,有强弱软虚四种引用,它们都和垃圾回收流程密切相关,在项目里,我们可以通过合理地使用不同类型的引用来优化代码的内存使用性能. 指向通过new得到的内存空间的引用叫强引用.比如有Stri ...

  9. Java的四种引用方式

    Java的四种引用方式 java内存管理分为内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指向该对象. java对象的引用包括   强引用,软引用,弱引用,虚引用 Jav ...

最新文章

  1. [国家集训队]最长双回文串 manacher
  2. 第一次使用Winhex直接修改文件二进制数据
  3. Day 21:Docker 入门教程
  4. 提高电脑反应速度_宁美千元价电脑,一体机设计+21英寸屏,办公娱乐选它
  5. NETCore Bootstrap Admin 通用后台管理权限 [1]: 前后台分离系统简介
  6. 微信小程序将于 2017 年 1 月 9 日正式开放
  7. 基于JAVA+SpringBoot+Mybatis+MYSQL的共享自习室预约管理系统
  8. EXCEL的底层实现
  9. .net core 中 Identity Server 4 Topic 之 Startup
  10. HTML——表格的快速生成以及表格的合并
  11. 怎么获取c++股票数据接口?
  12. 电机学他励直流发电机matlab,直流发电机综合实验指导书(全文5篇)
  13. 将人民币大写金额格式转为数字金额格式C#代码
  14. 利用讯飞语音识别技术开发离线语音控制系统(Windows平台)
  15. Python描述 LeetCode 13.罗马数字转整数
  16. SysML实践指南第二版(中文翻译:刘亚龙)第七章 使用模块图(BDD)建模
  17. 使用Clang作为编译器 —— Clang 中的Diagnostic flags
  18. 【升级版】python全自动定时,循环发消息(微信、QQ),零基础应用,
  19. 通信教程 | 常见串行通信基础原理
  20. 【Linux问题栏】虚拟机中无法识别电脑摄像头和usb摄像头

热门文章

  1. opendir php 返回值,php中opendir函数的用法详解
  2. [转]SATA电源线和数据线接口定义
  3. 【mysql安装问题】mysqld: Can‘t create directory ‘E: oft\mysql\mysql-5.7.19-winx64\data\‘ 两种解决办法
  4. 10大电子商务创新案例集合
  5. Android清理内存
  6. 百度贴吧顶帖,没了发发久依然有办法!
  7. seowhy论坛随机顶帖,不减积分的分区fid=2
  8. [.NET逆向] 【.NET】UnpackMe!Shielden+DNGuard,双层变异壳 - 脱壳详解 [复制链接]
  9. php常驻内存插件,轻量级常驻内存型 PHP API 开发框架 LinkPHP
  10. python技能排名_Python获取暗黑破坏神3战网前1000命位玩家的英雄技能统计