轉載自:http://blog.csdn.net/linux1s1s/article/details/46959649
預熱知識
測試前,我們需要先明白這樣一個問題
Java Heap / Native Heap 各自代表什麼?
Bitmap 到底是分配在Java heap上 還是分配到了Native heap上
Java Heap 大小一般是多大,有限制嗎?
Native Heap大小一般是多大,有限制嗎?
Java OOM 一般是發生在什麼時候,和Java Heap有關還是和 Native Heap有關
如果以上問題不是很清楚的話可以參考這個鏈接,自己惡補一下基礎知識:Android進程的內存管理分析
關於上面的幾個問題,這裏可以小結一下:
Java Heap是對於Java 虛擬機而說的,一般的大小上限是 16M 24M 48M 76M 具體視手機而定。
Native Heap是對於C/C++直接操縱的系統堆內存,所以它的上限一般是具體RAM的2/3左右。
所以對於2G的手機而言,Java Heap 大概76M,而Native Heap是760M左右,相差10倍。
那麼Android爲啥這麼吝嗇,給Java Heap分配了這麼點內存呢?
Google 既然這麼做了,自然有他的道理: 這樣設計的目的是爲了讓Android系統能同時讓比較多的進程常駐內存,這樣程序啓動時就不用每次都重新加載到內存,能夠給用戶更快的響應。迫使每個應用程序使用較小的內存,移動設備非常有限的RAM就能使比較多的app常駐其中。
我們知道在大多數的Android APP中OOM大多數發生在加載多圖片的時候,而很多人會認爲Bitmap的實例構造是在JNI層完成的,所以也應該在Native層纔對,其實不對,雖然在Native層完成,但是Bitmap的實例構造還是通過Android的虛擬機環境完成的,所以還是在Java Heap中。
對比測試
上面幾個問題回答清楚了,接下來我們看看迄今爲止比較火的幾個Image Loader庫
初始化狀態
Fresco
Glide
UIL
Volley
Fresco+OkHttp
Picasso
小結
這裏需要說清楚的是,其中並非都是靜態圖,還有大量的Gif動態圖,所以,評測的平均加載時間就不太客觀了,我們重點看一下上面我們提及的幾個概念:
Java Heap 和 Native Heap
從上面的測試可以看出: Frasco/Frasco + OkHttp 表現的和其他幾個迥異,前者會動態調整Native Heap而基本保持Java Heap 穩定, 其他幾個是相反的。而Java Heap的增長會直接導致OOM的出現。所以可以肯定的說 Frasco可以有效的避免OOM,同時 Frasco還可以顯示動態圖以及其他特性
基於以上的測試可以發現,孰優孰劣, 一辯便知。