RootType
enum RootType {
kRootUnknown = 0,
kRootJNIGlobal,
kRootJNILocal,
kRootJavaFrame,
kRootNativeStack,
kRootStickyClass,
kRootThreadBlock,
kRootMonitorUsed,
kRootThreadObject,
kRootInternedString,
kRootFinalizing, // used for HPROF's conversion to HprofHeapTag
kRootDebugger,
kRootReferenceCleanup, // used for HPROF's conversion to HprofHeapTag
kRootVMInternal,
kRootJNIMonitor,
};
RootInfo
class RootInfo {
public:
// Thread id 0 is for non thread roots.
explicit RootInfo(RootType type, uint32_t thread_id = 0)
: type_(type), thread_id_(thread_id) {
}
RootInfo(const RootInfo&) = default;
virtual ~RootInfo() {
}
private:
const RootType type_;
const uint32_t thread_id_;
};
VisitRootFlags
enum VisitRootFlags : uint8_t {
kVisitRootFlagAllRoots = (1 << 0),
kVisitRootFlagNewRoots = (1 << 1),
kVisitRootFlagStartLoggingNewRoots = (1 << 2),
kVisitRootFlagStopLoggingNewRoots = (1 << 3),
kVisitRootFlagClearRootLog = (1 << 4),
kVisitRootFlagClassLoader = (1 << 5),
// There is no (1 << 6).
kVisitRootFlagPrecise = (1 << 7),
};
Runtime::VisitRoots是访问虚拟机进程中所有root对象的入口
void Runtime::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) {
VisitNonConcurrentRoots(visitor, flags);
VisitConcurrentRoots(visitor, flags);
}
VisitThreadRoots(visitor, flags);
VisitNonThreadRoots(visitor);
}
void Runtime::VisitThreadRoots(RootVisitor* visitor, VisitRootFlags flags) {
thread_list_->VisitRoots(visitor, flags);
}
void Runtime::VisitNonThreadRoots(RootVisitor* visitor) {
java_vm_->VisitRoots(visitor);
sentinel_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
pre_allocated_OutOfMemoryError_when_throwing_exception_
.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
pre_allocated_OutOfMemoryError_when_throwing_oome_
.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
pre_allocated_OutOfMemoryError_when_handling_stack_overflow_
.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
pre_allocated_NoClassDefFoundError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal));
VisitImageRoots(visitor);
verifier::ClassVerifier::VisitStaticRoots(visitor);
VisitTransactionRoots(visitor);
}
Thread
void Thread::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) {
if ((flags & VisitRootFlags::kVisitRootFlagPrecise) != 0) {
VisitRoots</* kPrecise= */ true>(visitor);
} else {
VisitRoots</* kPrecise= */ false>(visitor);
}
}
(1) jni函数调用时,引用型参数会借助一个HandleScope保存在栈上。HandleScopeVisitRoots函数将遍历tlsPtr_top_handle_scope链表,然后访问其中的引用型对象。
template <bool kPrecise>
void Thread::VisitRoots(RootVisitor* visitor) {
const uint32_t thread_id = GetThreadId();
visitor->VisitRootIfNonNull(&tlsPtr_.opeer, RootInfo(kRootThreadObject, thread_id));
if (tlsPtr_.exception != nullptr && tlsPtr_.exception != GetDeoptimizationException()) {
visitor->VisitRoot(reinterpret_cast<mirror::Object**>(&tlsPtr_.exception),
RootInfo(kRootNativeStack, thread_id));
}
if (tlsPtr_.async_exception != nullptr) {
visitor->VisitRoot(reinterpret_cast<mirror::Object**>(&tlsPtr_.async_exception),
RootInfo(kRootNativeStack, thread_id));
}
visitor->VisitRootIfNonNull(&tlsPtr_.monitor_enter_object, RootInfo(kRootNativeStack, thread_id));
tlsPtr_.jni_env->VisitJniLocalRoots(visitor, RootInfo(kRootJNILocal, thread_id));
tlsPtr_.jni_env->VisitMonitorRoots(visitor, RootInfo(kRootJNIMonitor, thread_id));
//(1)
HandleScopeVisitRoots(visitor, thread_id);
// Visit roots for deoptimization.
if (tlsPtr_.stacked_shadow_frame_record != nullptr) {
RootCallbackVisitor visitor_to_callback(visitor, thread_id);
ReferenceMapVisitor<RootCallbackVisitor, kPrecise> mapper(this, nullptr, visitor_to_callback);
for (StackedShadowFrameRecord* record = tlsPtr_.stacked_shadow_frame_record;
record != nullptr;
record = record->GetLink()) {
for (ShadowFrame* shadow_frame = record->GetShadowFrame();
shadow_frame != nullptr;
shadow_frame = shadow_frame->GetLink()) {
mapper.VisitShadowFrame(shadow_frame);
}
}
}
for (DeoptimizationContextRecord* record = tlsPtr_.deoptimization_context_stack;
record != nullptr;
record = record->GetLink()) {
if (record->IsReference()) {
visitor->VisitRootIfNonNull(record->GetReturnValueAsGCRoot(),
RootInfo(kRootThreadObject, thread_id));
}
visitor->VisitRootIfNonNull(record->GetPendingExceptionAsGCRoot(),
RootInfo(kRootThreadObject, thread_id));
}
if (tlsPtr_.frame_id_to_shadow_frame != nullptr) {
RootCallbackVisitor visitor_to_callback(visitor, thread_id);
ReferenceMapVisitor<RootCallbackVisitor, kPrecise> mapper(this, nullptr, visitor_to_callback);
for (FrameIdToShadowFrame* record = tlsPtr_.frame_id_to_shadow_frame;
record != nullptr;
record = record->GetNext()) {
mapper.VisitShadowFrame(record->GetShadowFrame());
}
}
for (auto* verifier = tlsPtr_.method_verifier; verifier != nullptr; verifier = verifier->link_) {
verifier->VisitRoots(visitor, RootInfo(kRootNativeStack, thread_id));
}
// Visit roots on this thread's stack
RuntimeContextType context;
RootCallbackVisitor visitor_to_callback(visitor, thread_id);
ReferenceMapVisitor<RootCallbackVisitor, kPrecise> mapper(this, &context, visitor_to_callback);
mapper.template WalkStack<StackVisitor::CountTransitions::kNo>(false);
for (auto& entry : *GetInstrumentationStack()) {
visitor->VisitRootIfNonNull(&entry.second.this_object_, RootInfo(kRootVMInternal, thread_id));
}
}