首页 > 编程语言 > 详细

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

时间:2020-08-16 10:26:30      阅读:81      评论:0      收藏:0      [点我收藏+]

下面接着上一篇介绍第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)你不可不知的Java引用类型之——SoftReference源码详解

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

  

 

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

原文:https://www.cnblogs.com/mazhimazhi/p/13503996.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!