接前文, 之前讲了一堆 mtrace/memwatch/dmalloc/valgrind , 然并卵, 在 android 上都没法用, 我能怎样, 我也很绝望啊 !
难道还用 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/
转载请注明原文地址: https://ju.6miu.com/read-675649.html