1]是否有人指向文档或详细解释“Ext根扫描”在G1 GC中是如何工作的,特别是对于JNI句柄?(如有可能,请专门针对Java 7)
2]额外好处:我们可以期望openJDK gc的G1代码来自Hotspot吗?如果我们可以预期这是相同的,请您指出openJDK代码的相关部分,用于G1 GC ext根扫描?
谢谢
发布于 2017-05-13 03:54:31
概述
来自甲骨文
在执行垃圾回收时,G1的操作方式类似于CMS收集器。G1执行一个并发的全局标记阶段,以确定整个堆中对象的活性。
而外根区域扫描是标记过程中的一个阶段。
来自Java Performance Companion:
在此阶段,将扫描外部(堆外)根,例如JVM的系统字典、VM数据结构、JNI线程句柄、硬件寄存器、全局变量和线程堆栈根,以确定当前暂停集合集(CSet)中是否有任何点。
详细资料及守则
是的,我们可以预期openjdk的g1和hotspot的代码与这里声明的相同。因此,我们可以通过读取源代码来解释详细的过程。
void
G1CollectedHeap::
g1_process_strong_roots(bool collecting_perm_gen,
SharedHeap::ScanningOption so,
OopClosure* scan_non_heap_roots,
OopsInHeapRegionClosure* scan_rs,
OopsInGenClosure* scan_perm,
int worker_i) {
//...
process_strong_roots(false, // no scoping; this is parallel code
collecting_perm_gen, so,
&buf_scan_non_heap_roots,
&eager_scan_code_roots,
&buf_scan_perm);
//...
}然后在process_strong_roots
// Global (strong) JNI handles
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
JNIHandles::oops_do(roots);关于JNI的核心过程:它迭代JNI处理块,并找出这个句柄块的oop (oop: Java的引用抽象)是否指向堆区域,这意味着这个JNI oop是否可以是gc的根。
for (JNIHandleBlock* current = current_chain; current != NULL;
current = current->_next) {
assert(current == current_chain || current->pop_frame_link() == NULL,
"only blocks first in chain should have pop frame link set");
for (int index = 0; index < current->_top; index++) {
oop* root = &(current->_handles)[index];
oop value = *root;
// traverse heap pointers only, not deleted handles or free list
// pointers
if (value != NULL && Universe::heap()->is_in_reserved(value)) {
f->do_oop(root);
}
}
// the next handle block is valid only if current block is full
if (current->_top < block_size_in_oops) {
break;
}
}然后,在数组中记住这个根,当数组满时由OopClosure处理,在这种情况下,迭代根的引用来标记活动对象。
更多信息:
https://stackoverflow.com/questions/43615989
复制相似问题