Android內存分析和調優(下)

原文:http://www.cnblogs.com/zdwillie/p/3287150.html

最後一部分是關於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也很值得參考。有時間再在這個級別做更多的優化。

發佈了53 篇原創文章 · 獲贊 9 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章