App效能測試前需要瞭解的記憶體原理

來源:互聯網
上載者:User

標籤:gre   home鍵   number   body   selector   現象   shel   瞭解   主題樣式   

這兩天在研究效能中記憶體方面的一塊,網上也零散看了挺多文章,寫得很細但是感覺不夠整體,所以這篇算是總結一下吧,當個複習資料。 
那麼這裡個人分為兩個大部分,第一部分應用內的記憶體管理,主要是oom的理解,GC機制和記憶體泄露這三個小部分;另一部分是系統層級的記憶體管理,包括記憶體共用,進程建立到LMK也就是消亡的一個簡要瞭解,具體到某個細節,網上挺多的,就不細說了,後續看心情再補寫⑧!

應用內的記憶體管理一)為什麼會發生OOM

Android系統為每一個啟動並執行程式都指定了一個最大運行記憶體,超過這個值則會觸發OOM機制,反應在介面就是閃退、crash現象,導致OOM發生的原因比如記憶體泄露或者是代碼不考慮後果使用大量的資源,都有可能導致OOM出現的。OOM的臨界值可以通過adb shell getprop | grep ‘heap’查看到 
 
比如這裡,heapgrowthlimit是預設單個app最大記憶體,heapsize則是manifest檔案裡設定android:largeHeap=”true”,則會使用這個最大值。

二)android裡的GC機制

GC機制沿用了java的GC機制,當需要新記憶體去指派至的時候而剩餘不夠的時候,會觸發GC,把無用的對象回收掉,其中一個重要的演算法便是分代式演算法,這個演算法把虛擬機器分為年輕代、老年代和持久代,對象先分配到年輕代,然後GC多次後還存活的將會移動到老年代,老年代就不會頻繁觸發GC機制,一般觸發頻繁的都是年輕代的對象。

三)為什麼會記憶體泄露

第二點我們知道了GC機制,那麼如果GC過後程式還是沒有記憶體,那麼會發生OOM,導致GC後還是沒有足夠記憶體配置新對象的主要原因就是記憶體泄露了。首先要知道記憶體泄露也就是GC不掉的根源是生命週期長的對象持有生命週期短的對象,導致無用的對象一直無法回收。下面來看看幾個典型的分類:

**靜態類相關的泄露:**static對象的生命週期伴隨著整個程式的生命週期,所以這塊要注意不要把一些對象引用添加到static對象裡面去,會造成與之關聯的對象無法回收。

各種資源的釋放:很多了,包括cursor的關閉,IO流的關閉,bitmap的回收等等,進行一些帶有緩衝的資源一定要關閉或者釋放。

Handler的泄露:調用handler的delay的時候,會被認為對象是有用的,導致無法回收,還有handler開啟線程去下載東西沒有下載完成的時候,也會因為線程導致無法回收activity;或者使用handlerThread的時候,有延遲的方法,都會導致無法回收。其主要原因在於handler是持有activity的引用,你看主線程不是內建一個Looper然後給handler用嘛,導致有關聯關係。

各種註冊引用方法:比如一個常駐的後台線程處理某些時間,把當前對象註冊,因為一直持有對象引用,導致這個activity一直保留,所以不用的時候需要反註冊。

把對象緩衝進容器內卻忘記remove掉:有時候為了加快頁面響應,結果緩衝一些對象到容器內,結果越加越多,然後掛掉,網上有這個例子,雖然我暫時還沒碰到,一塊寫了。

系統層級的記憶體管理一) zygote的記憶體共用

我們知道我們的應用進程都是由zygote fork()出來的,包括系統服務和使用者程式。這塊的記憶體共用主要共用的是通用的資源記憶體,比如內建的主題樣式,這樣就避免了浪費記憶體空間讀取一樣的資源了。

二)LMK機制和oom_adj的值

Android核心有個專用的驅動low-memory-kill,當系統層級的記憶體不夠的時候會根據oom_adj的值以及記憶體配置狀況去kill掉某個進程,oom_adj可以在/proc/[pid]/oom_adj看到,並且這個值會隨著進程的狀態改變而改變,比如系統進程一般是-16,越大越容易被幹掉

三) 5個進程的優先順序

前台進程:當前啟動並執行,基本不死 
可見進程:介面可以見到,比如被遮擋 
服務進程:進程帶後台服務的,比如播放器 
後台進程:點擊home鍵,但不退出,就是後台進程了,有比較大幾率會被殺 
空進程:退出應用程式,還在後台保留這空進程,為的是加快啟動速率,最優先殺的對象

四) 共用記憶體

安卓的記憶體的管理是分頁和記憶體映射的,一個android程式啟動並執行時候,會把虛擬記憶體通過記憶體映射的方式給到啟動並執行進程,當真正要執行這塊內容的時候,會通過分頁的當時去分配實際記憶體,那麼虛擬記憶體包括什麼東西呢? 
在linux環境下,通過命令

pmap -x [pid]
  • 1

可以查詢虛擬記憶體空間執行個體 
 
 
可以看到虛擬記憶體的空間主要是包括這些的,程式碼片段,堆棧,匿名共用記憶體,動態連結程式庫等等。 
這裡又出現了一個名詞,匿名共用記憶體,實際上這是系統開闢一個記憶體空間,然後映射到進程的虛擬空間,可以實現多進程共用,比如android的顯示過程,處理好的surface交給surfaceFlinger服務,服務則是通過匿名共用記憶體的方式給緩衝區再進一步繪製我們看到的映像。 
好了,總結一下,android涉及的共用記憶體,一個是zygote生出的子代,共用android的一些資源,一些類庫,一些資料。第二個是匿名共用記憶體,包括surface,圖形驅動音頻驅動等等。

轉至:http://blog.csdn.net/Cloud_Huan/article/details/51146103

App效能測試前需要瞭解的記憶體原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.