MAT help文档中的注释
Garbage Collection Roots
A garbage collection root is an object that is accessible from outside the heap. The following reasons make an object a GC root:
System Class
Class loaded by bootstrap/system class loader. For example, everything from the rt.jar like java.util.* .
JNI Local
Local variable in native code, such as user defined JNI code or JVM internal code.
JNI Global
Global variable in native code, such as user defined JNI code or JVM internal code.
Thread Block
Object referred to from a currently active thread block.
Thread
A started, but not stopped, thread.
Busy Monitor
Everything that has called wait() or notify() or that is synchronized. For example, by calling synchronized(Object) or by entering a synchronized method. Static method means class, non-static method means object.
Java Local
Local variable. For example, input parameters or locally created objects of methods that are still in the stack of a thread.
Native Stack
In or out parameters in native code, such as user defined JNI code or JVM internal code. This is often the case as many methods have native parts and the objects handled as method parameters become GC roots. For example, parameters used for file/network I/O methods or reflection.
Finalizable
An object which is in a queue awaiting its finalizer to be run.
Unfinalized
An object which has a finalize method, but has not been finalized and is not yet on the finalizer queue.
Unreachable
An object which is unreachable from any other root, but has been marked as a root by MAT to retain objects which otherwise would not be included in the analysis.
Java Stack Frame
A Java stack frame, holding local variables. Only generated when the dump is parsed with the preference set to treat Java stack frames as objects.
art虚拟机中的gcroot枚举
enum RootType {
kRootUnknown = 0,
kRootJNIGlobal,//env->newGlobalRef
kRootJNILocal, //env->newlocalRef
kRootJavaFrame, //java栈帧
kRootThreadObject, //线程对象本身,对应java Thread对象
kRootFinalizing, // used for HPROF's conversion to HprofHeapTag
kRootReferenceCleanup, // used for HPROF's conversion to HprofHeapTag
kRootJNIMonitor, //线程锁,synchonized关键字处理对象锁的时候会用到
};
怎么扫描gcroot的
art虚拟机中cc(concurren_copying)算法会把gcroot拷贝到regionspace的tospace类型的region中,
Thread相关的gcroot
1.kRootThreadObject 线程对象本身
2.kRootJNILocal,即通过newlocalRef添加到localRefenceTable中的java obj
在FlipThreadRoots 方法中会调用
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));
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());
}
}
// 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);
}
全局的gcroot
void Runtime::VisitNonThreadRoots(RootVisitor* visitor) {
java_vm_->VisitRoots(visitor); //kRootGlobal
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);
class_linker_->VisitTransactionRoots(visitor);
}