前言
本文介绍Dalvik虚拟机中的AllocationTracker,用于追踪dalvik内存分配,能直观的看到分配了什么对象,和分配对象的堆栈。
Dalvik虚拟机
dalvik在dalvik/vm/AllocTracker.cpp中记录了内存分配、堆栈等;
dvmAllocTrackerStartup
在虚拟机启动时即调用了,可以通过hook调用依次如下三个方法即可,- 调用
dvmDumpTrackedAllocations
时会将存储下来的信息打印在logcat中。
// 开启追踪
bool dvmEnableAllocTracker()
// 生成记录
bool dvmGenerateTrackedAllocationReport(u1** pData, size_t* pDataLen)
// dump出来,打印到logcat里
void dvmDumpTrackedAllocations(bool enable)
/*
* Record the details of an allocation.
*/
// 从如下结构体就能看出来dalvik记录了些什么。他记录了分配了什么类型的对象、分配了多大、线程id、和分配时的堆栈。
struct AllocRecord {
ClassObject* clazz; /* class allocated in this block */
u4 size; /* total size requested */
u2 threadId; /* simple thread ID; could be recycled */
/* stack trace elements; unused entries have method==NULL */
struct {
const Method* method; /* which method we're executing in */
int pc; /* current execution offset, in 16-bit units */
} stackElem[kMaxAllocRecordStackDepth];
};
ART虚拟机
art/runtime/debugger.h,可以通过hook调用依次如下三个方法即可。
- 在虚拟机启动时调用
SetAllocTrackingEnabled
方法开启追踪; GetRecentAllocations
返回追踪的数据,类型是array,可以存储到文件里。这点比dalvik好一点,dalvik是输出到logcat里,还需要写脚本分析logcat;art可以直接输出到文件里,捞取出来后方便分析。
/*
* Allocation tracking support.
*/
static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
static jbyteArray GetRecentAllocations()
REQUIRES(!Locks::alloc_tracker_lock_) SHARED_REQUIRES(Locks::mutator_lock_);