G1 gc上"Ext Root Scanning"的文档/代码/详细解释?

car*_*org 5 java garbage-collection g1gc

1]任何人都可以指向文档或详细解释"Ext Root Scanning"在G1 GC中是如何工作的,特别是对于JNI句柄吗?(如果可能请特定于Java 7)

2]奖励:我们期望G1 gc的openJDK代码与Hotspot有什么不同?如果我们可以期望它是相同的,那么请指出用于G1 GC ext root扫描的openJDK代码的相关部分吗?

谢谢

Ton*_*ony 4

概述

\n\n

来自Oracle 文档

\n\n
\n

当执行垃圾收集时,G1 的操作方式与 CMS 收集器类似。G1 执行并发全局标记阶段来确定整个堆中对象的活跃度。

\n
\n\n

外部根区域扫描是标记过程的阶段之一。

\n\n

来自 Java 性能伴侣:

\n\n
\n

在此阶段,将扫描外部(堆外)根,例如 JVM\xe2\x80\x99s 系统字典、VM 数据结构、JNI 线程句柄、硬件寄存器、全局变量和线程堆栈根,以查找是否有任何点进入当前的pause\xe2\x80\x99s收集集(CSet)。

\n
\n\n

详细信息和代码

\n\n

是的,我们可以预期 openjdk 和 hotspot 的 g1 代码与此处所述相同。所以我们可以通过阅读源码来解释详细的过程。

\n\n

来自G1CollectedHeap

\n\n
void\nG1CollectedHeap::\ng1_process_strong_roots(bool collecting_perm_gen,\n                        SharedHeap::ScanningOption so,\n                        OopClosure* scan_non_heap_roots,\n                        OopsInHeapRegionClosure* scan_rs,\n                        OopsInGenClosure* scan_perm,\n                        int worker_i) {\n  //...\n  process_strong_roots(false, // no scoping; this is parallel code\n                       collecting_perm_gen, so,\n                       &buf_scan_non_heap_roots,\n                       &eager_scan_code_roots,\n                       &buf_scan_perm);\n  //...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在process_strong_roots

\n\n
  // Global (strong) JNI handles\n  if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))\n    JNIHandles::oops_do(roots);\n
Run Code Online (Sandbox Code Playgroud)\n\n

而JNI的核心流程是:迭代JNI句柄块,判断这个句柄块的oops(oop:Java的引用抽象)是否指向堆区,也就是说这个JNI oops是否可以是根对于GC。

\n\n
for (JNIHandleBlock* current = current_chain; current != NULL;\n     current = current->_next) {\n  assert(current == current_chain || current->pop_frame_link() == NULL,\n    "only blocks first in chain should have pop frame link set");\n  for (int index = 0; index < current->_top; index++) {\n    oop* root = &(current->_handles)[index];\n    oop value = *root;\n    // traverse heap pointers only, not deleted handles or free list\n    // pointers\n    if (value != NULL && Universe::heap()->is_in_reserved(value)) {\n      f->do_oop(root);\n    }\n  }\n  // the next handle block is valid only if current block is full\n  if (current->_top < block_size_in_oops) {\n    break;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,这个根被记住在一个数组中,OopClosure当数组满时进行处理,在这种情况下,迭代根的引用来标记活动对象。

\n\n

更多的:

\n\n\n