下面接着上一篇介绍第2阶段和第3阶段的处理逻辑。

2、process_phase2()

第2个阶段移除所有的referent还存活的Reference,也就是从refs_list中移除Reference。process_phase2()方法的实现如下:

// Phase2: remove all those references whose referents are reachable.
inline void process_phase2(DiscoveredList& refs_list,
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc) {
// complete_gc is ignored in this case for this phase
pp2_work(refs_list, is_alive, keep_alive);
// ...
}

在第2阶段移除所有的对象可达的Reference,因为不需要进行垃圾回收。

// Traverse the list and remove any Refs that are not active, or
// whose referents are either alive or NULL.
void ReferenceProcessor::pp2_work(
DiscoveredList& refs_list,
BoolObjectClosure* is_alive,
OopClosure* keep_alive
) {
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
iter.load_ptrs(); if (iter.is_referent_alive()) { // The referent is reachable after all.
// Remove Reference object from list.
iter.remove();
// Update the referent pointer as necessary: Note that this
// should not entail any recursive marking because the
// referent must already have been traversed.
iter.make_referent_alive();
iter.move_to_next();
} else {
iter.next();
}
}
}

调用iter.is_referent_alive()方法判断,如果referent还存活,那么从refs_list中删除对应的Reference对象即可。这个操作对于所有的引用类型(软引用、弱引用、幻像引用和最终引用)都一样。

3、process_phase3()

第3阶段在处理referent时,这个referent可以确保是存活状态,不过还需要做一些其它操作。process_phase3()方法的实现如下:

// Traverse the list and process the referents, by either
// clearing them or keeping them (and their reachable
// closure) alive.
void ReferenceProcessor::process_phase3(
DiscoveredList& refs_list,
bool clear_referent,
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc
) {
ResourceMark rm;
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
iter.update_discovered();
iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
if (clear_referent) {
// NULL out referent pointer
// 将Reference的referent字段置为null,之后会被GC回收
iter.clear_referent();
} else {
// keep the referent around
// 标记引用的对象为存活,该对象在这次GC将不会被回收
iter.make_referent_alive();
} iter.next();
}
// Remember to update the next pointer of the last ref.
iter.update_discovered();
// Close the reachable set
complete_gc->do_void();
}

对于软引用和弱引用来说,参数clear_referent的值为true,也就是当对象不可达后,引用字段就会被置为null,然后对象就会被回收(对于软引用来说,如果内存足够的话,在Phase 1,相关的引用就会从_refs_list中移除);对于最终引用和幻像引用来说, 参数clear_referent的值为false,也就意味着被这两种引用类型引用的对象,如果没有其他额外处理,只要Reference对象还存活,那引用的对象是不会被回收的。  

 

相关文章的链接如下:

1、在Ubuntu 16.04上编译OpenJDK8的源代码

2、调试HotSpot源代码

3、HotSpot项目结构 

4、HotSpot的启动过程

5、HotSpot二分模型(1)

6、HotSpot的类模型(2)

7、HotSpot的类模型(3)

8、HotSpot的类模型(4)

9、HotSpot的对象模型(5)

10、HotSpot的对象模型(6)

11、操作句柄Handle(7)

12、句柄Handle的释放(8)

13、类加载器

14、类的双亲委派机制

15、核心类的预装载

16、Java主类的装载

17、触发类的装载

18、类文件介绍

19、文件流

20、解析Class文件

21、常量池解析(1)

22、常量池解析(2)

23、字段解析(1)

24、字段解析之伪共享(2)

25、字段解析(3)

26、字段解析之OopMapBlock(4)

27、方法解析之Method与ConstMethod介绍

28、方法解析

29、klassVtable与klassItable类的介绍

30、计算vtable的大小

31、计算itable的大小

32、解析Class文件之创建InstanceKlass对象

33、字段解析之字段注入

34、类的连接

35、类的连接之验证

36、类的连接之重写(1)

37、类的连接之重写(2)

38、方法的连接

39、初始化vtable

40、初始化itable

41、类的初始化

42、对象的创建

43、Java引用类型

44、Java引用类型之软引用(1)

45、Java引用类型之软引用(2)

46、Java引用类型之弱引用与幻像引用

作者持续维护的个人博客  classloading.com

关注公众号,有HotSpot源码剖析系列文章!

   

参考文章:

(1)你不可不知的Java引用类型之——SoftReference源码详解

(2)深入理解JDK中的Reference原理和源码实现

  

Java引用类型之软引用(2)的更多相关文章

  1. Java引用类型之软引用(1)

    Java使用SoftReference来表示软引用,软引用是用来描述一些“还有用但是非必须”的对象.对于软引用关联着的对象,在JVM应用即将发生内存溢出异常之前,将会把这些软引用关联的对象列进去回收对 ...

  2. 你不可不知的Java引用类型之——软引用

    定义 软引用是使用SoftReference创建的引用,强度弱于强引用,被其引用的对象在内存不足的时候会被回收,不会产生内存溢出. 说明 软引用,顾名思义就是比较"软"一点的引用. ...

  3. Java引用类型之弱引用与幻像引用

    这一篇将介绍弱引用和幻像引用. 1.WeakReference WeakReference也就是弱引用,弱引用和软引用类似,它是用来描述"非必须"的对象的,它的强度比软引用要更弱一 ...

  4. Java引用类型之最终引用

    FinalReference类只有一个子类Finalizer,并且Finalizer由关键字final修饰,所以无法继承扩展.类的定义如下: class FinalReference<T> ...

  5. Java基础 之软引用、弱引用、虚引用 ·[转载]

    Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1)   交流分类:Java|笔记分类: Ja ...

  6. 你不可不知的Java引用类型之——虚引用

    定义 虚引用是使用PhantomReference创建的引用,虚引用也称为幽灵引用或者幻影引用,是所有引用类型中最弱的一个.一个对象是否有虚引用的存在,完全不会对其生命周期构成影响,也无法通过虚引用获 ...

  7. 你不可不知的Java引用类型之——弱引用

    定义 弱引用是使用WeakReference创建的引用,弱引用也是用来描述非必需对象的,它是比软引用更弱的引用类型.在发生GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收. 说明 弱 ...

  8. java中的软引用,弱引用,虚引用

    http://zh.wikipedia.org/wiki/%E5%BC%B1%E5%BC%95%E7%94%A8 有些语言包含多种强度的弱引用.例如Java,在java.lang.ref[1]包中定义 ...

  9. Java中的软引用、弱引用、虚引用的适用场景以及释放机制

    Java的强引用,软引用,弱引用,虚引用及其使用场景   从 JDK1.2 版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引 ...

随机推荐

  1. springAOP的三种实现方式

    springAOP的实现方式 三种 纯XML方式,XML+注解,纯注解方式. Spring 实现AOP思想使⽤的是动态代理技术 默认情况下, Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还 ...

  2. Java继承多态

    一. 父类引用指向子类对象父类名(接口名) 对象名=new 子类(接口)名称() 二. 父子继承关系中,成员变量重名1.直接通过子类对象访问成员变量 =左边是谁,就优先用谁2.间接通过成员方法访问成员 ...

  3. 2020数字中国创新大赛虎符网络安全赛道-pwn count

    比赛结束前半个小时才看的题,等我做出来比赛已经结束了.难受Orz 本地文件无法执行,远程调试. 题目大概意思就是让你计算200道四则运算.(实际上格式是固定的.先乘一次然后再加两次).200道题都正确 ...

  4. 【Go语言学习】匿名函数与闭包

    前言 入坑 Go 语言已经大半年了,却没有写过一篇像样的技术文章,每次写一半就搁笔,然后就烂尾了. 几经思考,痛定思痛,决定金盆洗手,重新做人,哦不,重新开始写技术博文. 这段时间在研究Go语言闭包的 ...

  5. PHP is_bool() 函数

    is_bool() 函数用于检测变量是否是布尔型.高佣联盟 www.cgewang.com PHP 版本要求:PHP 4, PHP 5, PHP 7 语法 bool is_bool ( mixed $ ...

  6. PHP fprintf() 函数

    实例 把一些文本写入到名为 "test.txt" 的文本文件: <?php高佣联盟 www.cgewang.com$number = 9;$str = "Beiji ...

  7. luogu P6087 [JSOI2015]送礼物 二分 单调队列 决策单调性

    LINK:送礼物 原本想了一个 \(nlog^2\)的做法 然后由于线段树常数过大 T到30. 以为这道题卡\(log^2\)没想到真的有神仙写\(log^2\)的过了 是我常数大了 抱歉. 能过的\ ...

  8. 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量

    LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...

  9. php+mysql+apache实现登录注册系统

    Php+mysql写网页注册登录系统 1.搭建msyql+php+apache的网站环境 (1) 在云服务器上搭建服务器,推荐使用宝塔集成 (2) 在本地windows搭建,推荐自己采用分开安装,这样 ...

  10. 如何在Spring异步调用中传递上下文

    以下文章来源于aoho求索 ,作者aoho 1. 什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步 ...