重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
在Android平臺上面,應用程序OOM異常永遠都是值得關注的問題。通常這一塊也是程序這中的重點之一。這下我就如何解決OOM作一點簡單的介紹。
潛山網站建設公司創新互聯,潛山網站設計制作,有大型網站制作公司豐富經驗。已為潛山1000+提供企業網站建設服務。企業網站搭建\成都外貿網站建設公司要多少錢,請找那個售后服務好的潛山做網站的公司定做!
首先,OOM就是內存溢出,即Out Of Memory。也就是說內存占有量超過了VM所分配的最大。
怎么解決OOM,通常OOM都發生在需要用到大量內存的情況下(創建或解析Bitmap,分配特大的數組等),在這樣的一種情況下,就可能出現OOM,據我現在了解到,多數OOM都是因為Bitmap太大。所以,這里我就專門針對如何解決Bitmap的OOM。其實最核發的就是只加載可見范圍內的Bitmap,試想這樣一種情況,在GridView或ListView中,數據量有5000,每一屏只顯示20個元素,那么不可見的,我們是不需要保存Bitmap在內在中的。所以我們就是只把那么可見的Bitmap保留在內存中,那些不可見的,就釋放掉。當元素滑出來時,再去加載Bitmap。
這里我有兩種方式,都可以避免OOM。
一,主動釋放Bitmap的內存
這種方式我簡單說一下,不太推薦,這也是我最開始使用的一種方法,但最后證明它不是最好的。(不推薦)
它的本質思路是:
1、只加載可見區域的Bitmap
2、滑動時不加載
3、停止滑動(Idle)后,開始重新加載可見區域的圖片
4、釋放滑出可見區域的Bitmap的內在。
它比較復雜:
1、我們需要監聽GridView/ListView的滑動事件,這個很簡單做到,AbsListView#setOnScrollListener(OnScrollListener l)
2、主動調用Bitmap#recycle()方法,它會導致一個問題,必須判斷這個Bitmap是否被一個View(ImageView等)所引用,如果被引用,我們不能簡單地調用recycle()方法,這樣會導致異常,說是View使用了一個已經被回收的Bitmap。
3,我們必須設計自己的線程來控制開始/暫停等,因為GridView/ListView的滑動狀態可能不斷地變化,也就是說滑動-停止-滑動,這種狀態可能不斷變化,這樣就會導致我們的線程中的run()方法里面的邏輯比較復雜,一旦復雜,問題就可能就得更多。
基于以上幾點,這種方式不是最好的,所以不推薦。
二,設計Cache
這種方式,我覺得是比較好的一種,它首先利用了cache,我認為cache是一個很重要的東西,把Bitmap的內存單獨放在一個地方來管理,這個地方就是cache,它的容量是一定的,我們可能會不斷的向這個cache中添加元素,也可能不斷的移除元素。
為了更好的說明這種方式,先要介紹一下LruCache。
LruCache
1、這其實就是一個LinkedHashMap,任意時刻,當一個值被訪問時,它就會被移動到隊列的開始位置,所以這也是為什么要用LinkedHashMap的原因,因為要頻繁的做移動操作,為了提高性能,所以要用LinkedHashMap。當cache滿了時,此時再向cache里面添加一個值,那么,在隊列最后的值就會從隊列里面移除,這個值就有可能被GC回收掉。
靜態代碼塊是在類加載進jvm時類實例化之前運行的,比如業務場景有這種類初始化時需要加載許多資源,在運行實例化類的時候會影響程序響應時間,所以就在項目啟動的時候加載類的時候就初始化了.非靜態代碼塊是在類實例化的時候才會運行,所以靜態代碼塊的執行一定在非靜態代碼塊執行之前執行.至于你上面的第一個問題要看具體業務場景和需求,賦值都可以實現.第二個問題,可能是寫那句代碼的人要看程序加載后有沒有執行那部分代碼而加上的,知道了靜態代碼塊和非靜態代碼塊的本質區別,為什么那么做和目的你就應該知道了.
當你裝載Chinese類的時候就會首先執行靜態代碼塊,所以你執行Chinese.sing(); 這句的時候首先裝載Chinese類,這時初始化這個類的時候就會先執行靜態代碼塊 static { count =2; System.out.println("static code"); }