这一节主要是对软引用处理器使用前的各重要属性初始化,为GC时对引用处理前的使用做准备,使用细节会在GC专题中讲。函数的调用入口在init.cpp->referenceProcessor_init()
void referenceProcessor_init() {
ReferenceProcessor::init_statics();
}
void ReferenceProcessor::init_statics() {
// We need a monotonically non-deccreasing time in ms but
// os::javaTimeMillis() does not guarantee monotonicity.
// 这里需要一个毫秒级的单调不递减时间,但是os::javaTimeNanos()是纳秒级的,不支持,所以这里要处理一下
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
// 初始化软引用的时间戳时钟
_soft_ref_timestamp_clock = now;
// 同时更新 java_lang_ref_SoftReference 类中clock属性字段
java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
// 创建软引用清除策略
_always_clear_soft_ref_policy = new AlwaysClearPolicy();
// 默认软引用标记策略 LRUMaxHeapPolicy LRUCurrentHeapPolicy 二选一,GC专题中会细讲
_default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
NOT_COMPILER2(LRUCurrentHeapPolicy());
if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
vm_exit_during_initialization("Could not allocate reference policy object");
}
guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
RefDiscoveryPolicy == ReferentBasedDiscovery,
"Unrecongnized RefDiscoveryPolicy");
// 这个值默认为 1,表示用discovered字段来标记挂起的对象引用
_pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
}
函数入中init.cpp->jni_handles_init()。java应用调用c/c++的函数是要通过jni来实现的,所以在虚拟机中,Java对象引用也都要用JNI句柄来持有。
void jni_handles_init() {
JNIHandles::initialize();
}
void JNIHandles::initialize() {
// 这里都比较简单,看下 JNIHandleBlock 类继承 CHeapObj,就知道 allocate_block 分配内存块是在C堆中,也就是说,下面两行代码的意义就是分配了
// 全局句柄块
_global_handles = JNIHandleBlock::allocate_block();
// 弱引用句柄块
_weak_global_handles = JNIHandleBlock::allocate_block();
EXCEPTION_MARK;
// We will never reach the CATCH below since Exceptions::_throw will cause
// the VM to exit if an exception is thrown during initialization
Klass* k = SystemDictionary::Object_klass();
// 已删除的对象的句柄,这块内存是在Java堆中分配的
_deleted_handle = InstanceKlass::cast(k)->allocate_instance(CATCH);
}