Java引用类型之软引用(2)
下面接着上一篇介绍第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对象还存活,那引用的对象是不会被回收的。
正文到此结束