下面接着上一篇介绍第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. Selenium自动化:有代码测试与无代码测试。这些你都懂了吗?

    大多数测试人员认为 Selenium是满足其测试自动化需求的自动化框架.作为全球测试人员使用的开放源框架, Selenium 无疑是测试人员适应日趋敏捷的公司的一种好方法.实际上, Selenium仍 ...

  2. 学习 bypass csp记录

    最近看到一篇bypas csp的记录复现学习下 配置csp 这里直接设置html头达到配置csp的效果. Content-Security-Policy: script-src 'self' 'uns ...

  3. 硬核干货:5W字17张高清图理解同步器框架AbstractQueuedSynchronizer

    前提 并发编程大师Doug Lea在编写JUC(java.util.concurrent)包的时候引入了java.util.concurrent.locks.AbstractQueuedSynchro ...

  4. thymeleaf js绑定多个变量参数

    写法一: <img th:src="@{/css/bianji.png}" th:onclick="|viewById('${user.id}','${user.i ...

  5. MySQL之高级操作

     新增数据: 基本语法: insert into 表名 [(字段列表)] values(列表值) 在数据插入的时候,假设主键对应的值已经存在,插入一定会失败 主键冲突: 当主键存在冲突的时候(Dupl ...

  6. [leetcode/lintcode 题解] 一致性哈希 II · Consistent Hashing II

    [题目描述] 在 Consistent Hashing I 中我们介绍了一个比较简单的一致性哈希算法,这个简单的版本有两个缺陷: 增加一台机器之后,数据全部从其中一台机器过来,这一台机器的读负载过大, ...

  7. 毫无基础的人入门Python,Python新手入门教程2

    1.6 面向对象和内存分析086.面向对象和面向过程的区别_执行者思维_设计者思维087.对象的进化故事088.类的定义_类和对象的关系089.构造函数__init__090.实例属性_内存分析091 ...

  8. 旧的成功的AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="htt ...

  9. 数据库层级关系转换为树结构的json

    原文链接:https://blog.csdn.net/Tonysdyp/article/details/80987959 首先是数据库设计: 通过查询数据库,将全局数据作为一个ArrayList< ...

  10. 虚拟机 NAT 网络静态ip配置记录

    环境 VMware 15.5.5 build-16285975 centos7 虚拟网络编辑器配置 位置 编辑 --> 虚拟网络编辑器 示例 以下以 192.168.18.0 网段ip为例,实际 ...