难道还用 linux 的传统方式, 看 /proc/slabinfo 和 /proc/$PID/smaps, 或者 procmem –p $PID 么? // MAGIC1. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
机智如我,当然只好去百度了...
一搜就能看到, 对于 malloc 部分的内存, Android 的 bionic C库本来就提供了类似的 malloc_debug 功能;
其中提供了 get_malloc_leak_info 函数 // MAGIC2. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
参考网页 http://blog.csdn.net/l_nan/article/details/43489573
该函数用于获取内存泄露信息, 在分配内存时,记录下调用堆栈 --------- 而我们可以使用这个来获取 malloc 的调用栈地址;
有了栈地址之后, 正常思路我们可以对照 /proc/$PID/maps 找到地址所对应的进程动态库, 然后根据偏移量用 addr2line -e 找到 malloc 对应代码的行号;
查内存泄漏可以这样搞法, 但是要确认内存使用量查起来就太多了, 还好看到一个 dladdr 调用, 可以粗略的获取到当前进程的符号表, 因此可以把代码写成:
get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); // MAGIC3. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
if(infoSize > 0)
count = overallSize / infoSize;
uint8_t *data = info;
for(int i =0; i < count; i++)
{
ALOGW("--------------- size = %d, dup = %d", *(int*)data, *(int*)(data+0x4));
for(int j=0; j<32; j++)
{
uintptr_t dloffset = 0;
const char* dlsymbol = NULL;
void* addr = *(void**)(data+8+j*4);
Dl_info dlinfo;
if(addr != NULL)
{
if (dladdr((void*)addr, &dlinfo) != 0) {
dloffset = reinterpret_cast<uintptr_t>(dlinfo.dli_saddr);
dlsymbol = dlinfo.dli_sname;
ALOGW("backtrace: 0x%x, dlsymbol = %s", addr, dlsymbol);
}
}
}
data += infoSize;
}
如果我们要确认 video 播放时所使用的内存分布, 就在 nuplayer 代码的起播前后位置分别加上以上这段, 分别打印出起播前后的 malloc size以及栈符号;
// MAGIC4. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
由对比图可以看到, 起播后所多出来的 malloc 栈, size 比较大的符号都是来自于 ffmpegAudio, ACodec 的 allocateBuffersOnPort, MPEG4Extractor 等;// MAGIC5. DO NOT TOUCH. BY 冗戈微言
一般来说, 播放过程的大头部分,都是在 omx input port 的 stream buffer 分配和 omx output port 的 VideoGrallocMetadata buffer分配 (比如上面的 ACodec allocateBuffersOnPort ), 以及其他的 parser / audio 等模块中, 而占用最大的 yuv buffer 对应的 ion 内存分配是体现在 SurfaceFlinger 进程中…… 另外还有 video 核的驱动部分在 kernel 中申请的部分,比如参考帧 buffer ......// MAGIC6. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
应该算是android 各模块都能通用的做法了吧~ // MAGIC7. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/
但题开的还是太大了, 贻笑大方 // MAGIC8. DO NOT TOUCH. BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/