上一篇講述了Valgrind,后續(xù)發(fā)現(xiàn)還有memory leak,但是Valgrind沒(méi)有給出詳細(xì)的調(diào)用信息,所以只能作罷,尋找其他工具。
從網(wǎng)上了解到DDMS有個(gè)隱藏的頁(yè)面,Native Heap。于是抱著試試看的態(tài)度,找來(lái)了一臺(tái)Android設(shè)備,刷了CM,這么做的目的是為了得到userdebug/eng版本的ROM(查看命令:
adb shell getprop ro.build.type),一般的官方ROM都是user的,沒(méi)有厲害的debug能力。于是開(kāi)工!
第一步:
setprop libc.debug.malloc 1。這里有四種prop可以設(shè)置,1是mem leak,5和10是內(nèi)存越界,20是虛擬機(jī)。可悲的是5和10并沒(méi)有被libc_malloc_debug庫(kù)完美地支持,所以只有1好用。
第二步,stop, start。這些操作都是在device shell里面做的。設(shè)備會(huì)快速重啟。
第三步,驗(yàn)證prop。getprop看看結(jié)果,然后ls一下,去logcat里看一下結(jié)果。如果結(jié)果都能對(duì)的上,那就可以繼續(xù)了。
第四步,在ddms.cfg文件最后增加一行native=true并save。ddms.cfg位于c:\Users\xxx\.android目錄下。
第五步,打開(kāi)單獨(dú)的ddms(確保eclipse沒(méi)有在跑),選擇Native Heap頁(yè)面,點(diǎn)擊snapshot按鈕。snapshot的過(guò)程有點(diǎn)慢。最后能看到每個(gè)so占用了多少內(nèi)存以及百分比。過(guò)一段時(shí)間snapshot一次就能看到每個(gè)so的趨勢(shì)了。
第六步,分析。snapshot顯示了分配內(nèi)存的地址(記做addressA),這個(gè)地址是RAM地址,不是so的相對(duì)地址。為了得到相對(duì)地址,需要ps一下,找到你的pid,然后cat /proc/pid/maps,找到so的起始地址(記做addressB)。然后拿addressA - addressB,得到相對(duì)地址,用addr2line定位到哪一處調(diào)用。這里我還用過(guò)objdump -dS libXXX.so > XXX.dump,把so反編譯出來(lái),分析XXX.dump,找到相對(duì)地址的調(diào)用位置,一看是_Znwj,這個(gè)就是new。其實(shí),搞來(lái)搞去最終定位到new,等于浪費(fèi)表情了。
這個(gè)工具遠(yuǎn)沒(méi)有Mac Instrument強(qiáng)大,它不能定位到哪個(gè)函數(shù)占用了多少內(nèi)存。它能做的就是告訴你哪個(gè)so的內(nèi)存增長(zhǎng)減少了,但其實(shí)這也很有用,把握好下一步的方向不也很關(guān)鍵嗎?
參考:http://bricolsoftconsulting.com/how-to-enable-native-heap-tracking-in-ddms/
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。