Android內存分析和調優(下)


最后一部分是關於native heap,.dex,/dev/other的優化。

Native Heap分析和優化

android的DDMS可以幫助查看c++ native heap的使用,但需要一定的配置,而且必須是root的手機。

  1. 在~/.android/ddms.cfg增加"native=true"。這樣子ddms才會有native heap的tab。
  2. 指向下面adb命令打開malloc的debug模式
    adb root
    adb shell setprop libc.debug.malloc 1
    adb shell stop
    adb shell start
  3. 打開standalone的DDMS(不是eclipse中那個,是獨立的應用程序,sdk目錄下有),然后在native heap這個tab下,可以查看native heap的分配情況。

      在很多手機上,即使執行了這些命令,還是看不到結果。原因是很多手機上並沒有安裝debug版本的malloc庫(包括libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so)。這篇經常被引用的文章介紹了一種方法。是從供大家刷機用的CyanogenMod image中提取這兩個文件,然后拷貝到自己的機器上。可以參考那片文章的具體步驟。

      下面的問題是只能看到地址而不知道文件名和行號。至少有下面一些辦法

  1. 使用ndk中的arm-linux-androideabi-gdb(android ndk的gdb)來打開.so文件。這里的.so不能使apk中使用的,因為那個已經把symbol給strip了。而應該使用 ***\obj\local\armeabi\***.so,這個是帶着symbol的。
    然后可以在gdb中使用info symbol 0x000xxxxx來定位到地址對應的函數名。這里的0x000xxxxx是ddms中地址把前三位變成0。因為gdb .so中使用.so的靜態地址,而ddms中的地址經過動態鏈接,是內存的虛擬地址。但動態鏈接並不改變地址的后五位,所以這里后五位保持不變,前三位變成0,從而轉換為so的靜態地址。
    然后用info line xxx.cpp:xxx來定位具體行。
    這個方法比較繁瑣,因為當時自己沒找到好辦法,就這么用的。
  2. 用ndk的arm-linux-androideabi-addr2line。后面跟so和0x000xxxxx。跟gdb差不多,會簡單一些。
  3. 有人說設置PATH加上包含addr2line的目錄,然后再設置ANDROID_PRODUCT_OUT可以在ddms中直接顯示函數名和行號,但沒有試過。

/other/dev分析和優化

自己用的是4.2版本的android。每次打開preference setting,/other/dev的private dirty都會增加很多(10M作用),並且不會釋放。通過查看smaps,發現是/dev/pvrsrvkm導致的(4.3后設備名改為kgsl-3d0)。這個是顯示相關的設備,按我的理解,大概是顯存(如果沒有獨立顯存,那是用於顯示的內存)。通過網上查詢,並不是只有我遇到這個問題。例如chrome也有這個問題。但還是不知道為何這個會增加。在一通亂試后,發現如果對activity設置android:hardwareAccelerated=false,就能解決。此時只增加shared dirty,並且關掉activity,內存會被釋放。后來再查,看到stackoverflow上這篇文章,才知道這是4.2的一個bug。4.3和4.1都沒有問題。

.Dex mmaps優化

這個是java代碼編譯只會的.dex文件的大小。

開始自己使用eclipse編譯出來的apk作性能分析,發現這個也有幾M。但release版本的卻不到1M。轉念一想,原來是proguard的作用。proguard是android自帶的混淆器,會對java的類名,函數名,變量名等重新命名,給一個非常短的名字。有兩個作用,一個是使得反編譯的代碼不容易理解,另一個就是減少了dex文件的大小。經過這次內存分析,才發現其效果還是非常明顯的。

因為proguard無法對res下的layout,xml文件做混淆,所以他們引用到的java類(例如一些view類)的名字是不能被改變的。所以一個小經驗是讓xml文件盡量少的引用java類,從而提高混淆的比例。

總結

關於android內存優化,自己就先做了這些。整體思路就是從宏觀到微觀,利用各種工具和網絡資料,從內存占用量最多的模塊下手,一步步的分析原因,解決問題。再細化下去,還有很多代碼級別的優化,例如perf tips里介紹了很多經驗,memory efficient java也很值得參考。有時間再在這個級別做更多的優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM