android-java.lang.OutOfMemoryError: bitmap size exceeds VM budge

This answer has 2 parts 

1) its not how much images the screen has, but being carefull on cleaning everything up when finishing the activity 

2) Android dev site (http://developer.android.com/resources/articles/future-proofing.html

Technique to Avoid, #3: Going Overboard with Layouts 

Due to changes in the View rendering infrastructure, unreasonably deep (more than 10 or so) or broad (more than 30 total) View hierarchies in layouts are now likely to cause crashes. This was always a risk for excessively complex layouts, but you can think of Android 1.5 as being better than 1.1 at exposing this problem. Most developers won't need to worry about this, but if your app has very complicated layouts, you'll need to put it on a diet. You can simplify your layouts using the more advanced layout classes like FrameLayout and TableLayout. 

Part II: 

Android一些性能優化的方法: 

1. 首先內存方面,可以參考 Android堆內存也可自己定義大小 和 優化Dalvik虛擬機的堆內存分配 

2. 基礎類型上,因爲Java沒有實際的指針,在敏感運算方面還是要藉助NDK來完成。Android123提示遊戲開發者,這點比較有意思的是Google 推出NDK可能是幫助遊戲開發人員,比如OpenGL ES的支持有明顯的改觀,本地代碼操作圖形界面是很必要的。 

3. 圖形對象優化,這裏要說的是Android上的Bitmap對象銷燬,可以藉助recycle()方法顯示讓GC回收一個Bitmap對象,通常對一個不用的Bitmap可以使用下面的方式,如 

if(bitmapObject.isRecycled()==false) //如果沒有回收  
         bitmapObject.recycle();   

4. 目前系統對動畫支持比較弱智對於常規應用的補間過渡效果可以,但是對於遊戲而言一般的美工可能習慣了GIF方式的統一處理,目前Android系統僅能預覽GIF的第一幀,可以藉助J2ME中通過線程和自己寫解析器的方式來讀取GIF89格式的資源。 

5. 對於大多數Android手機沒有過多的物理按鍵可能我們需要想象下了做好手勢識別 GestureDetector 和重力感應來實現操控。通常我們還要考慮誤操作問題的降噪處理。 

Android堆內存也可自己定義大小 

    對於一些大型Android項目或遊戲來說在算法處理上沒有問題外,影響性能瓶頸的主要是Android自己內存管理機制問題,目前手機廠商對RAM都比 較吝嗇,對於軟件的流暢性來說RAM對性能的影響十分敏感,除了上次Android開發網提到的 優化Dalvik虛擬機的堆內存分配 外,我們還可以強制定義自己軟件的對內存大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆內存爲例: 

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; 

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設置最小heap內存爲6MB大小。當然對於內存吃緊來說還可以通過手動干涉GC去處理,我們將在下次提到具體應用。 

優化Dalvik虛擬機的堆內存分配 

對於Android平臺來說,其託管層使用的Dalvik Java VM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型遊戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內存的處理效率。當然具體 原理我們可以參考開源工程,這裏我們僅說下使用方法:   private final static float TARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。 

Part III: 

捕獲OOM異常 

try { 

    …… 

} catch (OutOfMemoryError e) { 

    e.printStackTrace(); 

}

java.lang.OutOfMemoryError:bitmap size exceeds VM budget

是 Bitmap bm = BitmapFactory.decodeFile(path)引起的,Path是sd卡中圖片的路徑,如果圖片過大就會產生錯誤;

查找資料得知:
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 10;
Bitmap bmp=BitmapFactory.decodeFile(path,options);

修改採樣可以避免這個問題,但是這個inSampleSize該如何確定?1000*1000的圖片縮小10倍,可以避免內存溢出;但是本身很小的圖片也縮小10倍,並不是我想要的結果。。。。。怎麼做可以兼顧?
介紹一下圖片佔用進程的內存算法吧。
android中處理圖片的基礎類是Bitmap,顧名思義,就是位圖。佔用內存的算法如下:
圖片的width*height*Config。
如果Config設置爲ARGB_8888,那麼上面的Config就是4。一張480*320的圖片佔用的內存就是480*320*4 byte。
前面有人說了一下8M的概念,其實是在默認情況下android進程的內存佔用量爲16M,因爲Bitmap他除了java中持有數據外,底層C++的 skia圖形庫還會持有一個SKBitmap對象,因此一般圖片佔用內存推薦大小應該不超過8M。這個可以調整,編譯源代碼時可以設置參數。

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