最近在Android項目中遇到C++層內存泄露問題,在此記錄解決方法。
1.修改C:\Users\<用戶名>\.android\ddms.cfg,在文件的最後添加"native=true"。
2.連上真機並打開cmd命令行,執行以下幾步:
adb root //獲取root
adb shell setprop libc.debug.malloc 1 //設置檢測等級,這裏的1表示檢測內存泄露,其他參數可百度
adb shell stop
adb shell start
setprop libc.debug.malloc 1 這一步需要真機中有以下兩個文件:/system/lib/libc_malloc_debug_leak.so 與 /system/lib/libc_malloc_debug_qemu.so。
可以使用adb shell進入shell模式查看這兩個文件是否存在(使用linux控制檯指令)。
adb shell start這步之後可以使用 adb shell getprop查看libc.debug.malloc有沒有設置爲1。
3.打開ddms.bat,這個文件在sdk/tools裏,我的路徑是F:\adt-bundle\sdk\tools\ddms.bat。
這裏的ddms和adt中的ddms不一樣,會多出一個native heap選項卡。
左側的列表窗口會顯示真機中的所有進程,選擇需要檢測的進程(你的項目包名),
然後點下"Snapshot Current Native Heap Usage"按鈕,之後就會顯示native層的內存分配情況。
method那一欄會顯示進行分配內存的函數地址。
點擊上圖中的"+-"按鈕,可以在每次點擊"Snapshot"按鈕之後顯示內存增加情況。
定位到內存分配異常的那條,記錄下method的地址,然後通過下面幾步獲得具體函數。
4.記錄左側的列表窗口中需要檢測的進程的pid,打開cmd命令行,輸入adb shell進入shell模式,再輸入 cat proc/pid/maps。
輸入之後會打印很多進程的符號表,找到你的.so的起始地址,例如:5f930000 - 6a000000 ..... libTest.so,
這裏的5f930000就是起始地址。如果libTest.so之前有多個地址,使用第一個(這個不確定,如果最終定位的函數很奇怪,
就試試其他的吧)。
5.將D:\android-ndk-r9b\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin添加到環境變量PATH
中(這裏的目錄需要根據你的目標平臺設置)。添加到PATH是爲了方便使用這個目錄下的gdb,
也就是arm-linux-androideabi-gdb.exe這個。配置好後打開cmd命令行,輸入arm-linux-androideabi-gdb開啓gdb。
然後輸入 file <你的共享庫.so路徑>,gdb會載入共享庫的符號表。
計算真實函數地址0xXXXXXXXX = method地址 - 上一步得到的起始地址。 之後輸入 info symbol 0xXXXXXXXX 來定位函數。
通過以上步驟就可以定位到具體的函數了,如果有問題,歡迎留言。
參考網址:http://www.cnblogs.com/zdwillie/p/3287150.html(這篇的尋找method地址有誤)
http://www.360doc.com/content/14/0222/17/10366845_354796656.shtml