2011-01-06 25 views
25

Tôi đang cố gắng thay đổi bố cục của ứng dụng từ dọc sang ngang và ngược lại. Nhưng nếu tôi thực hiện thường xuyên hoặc nhiều hơn một lần thì thỉnh thoảng ứng dụng của tôi bị treo. Dưới đây là nhật ký lỗi. Xin đề nghị những gì có thể được thực hiện?java.lang.OutOfMemoryError: kích thước bitmap vượt quá ngân sách VM

01-06 09:52:27.787: ERROR/dalvikvm-heap(17473): 1550532-byte external allocation too large for this process. 01-06 09:52:27.787: ERROR/dalvikvm(17473): Out of memory: Heap Size=6471KB, Allocated=4075KB, Bitmap Size=9564KB 
01-06 09:52:27.787: ERROR/(17473): VM won't let us allocate 1550532 bytes 
01-06 09:52:27.798: DEBUG/skia(17473): --- decoder->decode returned false 
01-06 09:52:27.798: DEBUG/AndroidRuntime(17473): Shutting down VM 
01-06 09:52:27.798: WARN/dalvikvm(17473): threadid=3: thread exiting with uncaught exception (group=0x4001e390) 
01-06 09:52:27.807: ERROR/AndroidRuntime(17473): Uncaught handler: thread main exiting due to uncaught exception 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): java.lang.RuntimeException: Unable to start activity ComponentInfo{}: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3812) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.access$2300(ActivityThread.java:126) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1936) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.os.Looper.loop(Looper.java:123) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.main(ActivityThread.java:4595) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at java.lang.reflect.Method.invoke(Method.java:521) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at dalvik.system.NativeStart.main(Native Method) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.createView(LayoutInflater.java:513) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.inflate(LayoutInflater.java:385) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.Activity.setContentView(Activity.java:1629) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at onCreate(Game.java:98) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  ... 12 more 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.reflect.InvocationTargetException 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.widget.LinearLayout.<init>(LinearLayout.java:92) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at java.lang.reflect.Constructor.constructNative(Native Method) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at java.lang.reflect.Constructor.newInstance(Constructor.java:446) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.LayoutInflater.createView(LayoutInflater.java:500) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  ... 22 more 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:464) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:340) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.content.res.Resources.loadDrawable(Resources.java:1705) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.content.res.TypedArray.getDrawable(TypedArray.java:548) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.View.<init>(View.java:1850) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.View.<init>(View.java:1799) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  at android.view.ViewGroup.<init>(ViewGroup.java:296) 
01-06 09:52:27.857: ERROR/AndroidRuntime(17473):  ... 26 more 
+1

thời gian tiếp theo, sử dụng nút "định dạng mã", không phải nút "chặn trích dẫn".nút blockquote mess lên tin nhắn –

+1

Tôi cũng nhận được lỗi này, nhưng không có giải pháp nào. Tôi gặp phải lỗi này khi tôi đang cố gắng tải khung hình của tệp video từ lớp MetaDataRetriver, Mã của tôi \t MediaMetadataRetriever mRetriever = new MediaMetadataRetriever(); mRetriever.setDataSource (this.videoPath); for (int i = 0; i

+0

bản sao có thể có của [java.lang.OutOfMemoryError: kích thước bitmap vượt quá ngân sách VM - Android] (http://stackoverflow.com/questions/1949066/java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget- android) – akshay

Trả lời

0

Phân bổ 1550532 byte âm thanh lớn. Tôi đoán bố cục của bạn có một tham chiếu đến một hình ảnh bitmap của một số loại, một PNG có lẽ? Kích thước của PNG này là gì? Nếu nó thực sự lớn và bạn có nhiều hơn một vài người trong số họ, bạn có thể không có đủ bộ nhớ để tải chúng cùng một lúc.

Ngoài ra nếu điều này được kích hoạt bởi vòng quay, hãy nhớ rằng Hoạt động của bạn bị hủy và được tạo lại để bạn có thể cần phải cẩn thận với các tham chiếu tĩnh. Hãy xem điều này Google blog post. Bạn sẽ cần phải cẩn thận giữ các tham chiếu tĩnh đối với những thứ trong mã của mình có thể dẫn đến rò rỉ

3

Nguồn hình ảnh đến từ đâu? Bạn có ảnh 9MB trong thư mục drawables của mình không?

Có rất nhiều cuộc thảo luận về các vấn đề với quản lý bộ nhớ bitmap gốc của Android, ví dụ: http://code.google.com/p/android/issues/detail?id=10821, http://code.google.com/p/android/issues/detail?id=8488, http://groups.google.com/group/android-developers/browse_thread/thread/ed57849ef705d421/11af8362d77a8cf4?lnk=raot. Tôi đã có may mắn gọi một cách rõ ràng tái chế() và System.gc() mỗi khi tôi kết thúc với một bitmap, ví dụ:

private void changeImage() { 
    if (mCurrentImage != null) { 
      mCurrentImage.recycle(); 
      mCurrentImage = null; 
      System.gc(); 
    } 
    mCurrentImage = getNewImage(); 
} 
50

Một trong những lỗi phổ biến nhất mà tôi thấy phát triển Android Apps là lỗi

java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget

. Tôi tìm thấy lỗi này thường xuyên trên các Hoạt động sử dụng nhiều bitmap sau khi thay đổi hướng: Hoạt động bị hủy, được tạo lại và bố cục được "tăng tốc" từ XML tiêu thụ bộ nhớ VM có sẵn cho bitmap.

Ảnh bitmap trên bố cục Hoạt động trước đó không được người thu gom rác phân bổ hợp lý vì chúng đã tham chiếu chéo với hoạt động của chúng. Sau nhiều thử nghiệm, tôi đã tìm thấy một giải pháp khá tốt cho vấn đề này.

Thứ nhất, thiết lập các “id” thuộc tính trên quan điểm mẹ của layout XML của bạn:

<?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@+id/RootView"> 
     ... 

Sau đó, vào phương pháp onDestroy() của hoạt động của bạn, hãy gọi unbindDrawables() phương pháp thông qua một tài liệu tham khảo cho phụ huynh Xem và sau đó thực hiện System.gc().

@Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     unbindDrawables(findViewById(R.id.RootView)); 
     System.gc(); 
    } 

    private void unbindDrawables(View view) { 
     if (view.getBackground() != null) { 
      view.getBackground().setCallback(null); 
     } 
     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
       unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 
      ((ViewGroup) view).removeAllViews(); 
     } 
    } 

phương pháp unbindDrawables() này khám phá những cây xem đệ quy và:

  1. Loại bỏ callbacks trên tất cả các nền drawables
  2. Loại bỏ Childs trên mỗi ViewGroup
+0

điều này đã khắc phục được sự cố cho trường hợp của tôi ... luôn có ngoại lệ layoutinflate về việc tăng bố cục lớn với nhiều đồ họa sau thời gian ... cảm ơn! – cV2

+8

greate code ... chỉ có lỗi tôi đã có với điều này là khi có adapterView trong bố trí. Chúng gây ra một UnsupportedOperationException trên removeAllViews(), chỉ cần thêm một thử bắt trên dòng đó và tất cả mọi thứ làm việc tốt. –

+2

Làm cách nào để bạn xử lý ảnh nền được thêm bằng phương thức setTheme ?? – Maxrunner

8

Đây là một câu trả lời thực tế, những gì tôi đã cố gắng tránh sự cố này tại thời gian chạy

Runtime.getRuntime().gc(); 

Gọi thu gom rác là một ý tưởng hay.

12

tôi đã nhận được sự java.lang.OutOfMemoryError: Bitmap Kích Vượt lỗi VM ngân sách tại một số lần

1) Khi chuyển từ ứng dụng và quay trở lại ứng dụng một thời gian sau (Nhấn nút home và sau khi duyệt một số url)

2) Khi đăng nhập/đăng xuất vào ứng dụng thường xuyên (trong vòng 10 giây)

3) Khi chuyển đổi thiết bị theo chiều ngang/chiều dọc

Cuối cùng tôi giải quyết được lỗi trong sau cách

public void clearAllResources() { 

    // Set related variables null 

    System.gc(); 
    Runtime.getRuntime().gc(); 
    } 
+0

Vì tài liệu hiệu suất Android cho biết bạn không nên cố gắng ép buộc GC, bạn nên để Davlik tự xử lý nó. Tốt nhất là hãy tránh nguyên nhân gây ra vấn đề bộ nhớ của bạn và thay thế hiệu suất CPU – William

+0

@Rafiq, bạn có thể giải thích khi nào nên gọi hàm này clearAllResources()? – zhaojing

3

Điểm dừng đầu tiên ứng dụng của bạn từ đâm vào thời gian chạy bằng cách bắt lỗi OutOfMemory tại nơi mà bạn nghĩ rằng có thể tạo ra lỗi này như sau:

try { 

... 

} 
catch(OutOfMemoryError error) { 
    //decide what to do when there is not more memory available 
} 
3

Bạn có thể khắc phục vấn đề sử dụng opts.inSampleSize=2; or opts.inSampleSize=4

BitmapFactory.Options opts = new BitmapFactory.Options(); 
// opts.inJustDecodeBounds = true; 
opts.inSampleSize=2;  
Bitmap myBitmap = BitmapFactory.decodeFile(st_imagepath,opts); 
2

Tôi đã thực hiện một số tiện ích mở rộng cho câu trả lời tuyệt vời của @ hp.android:

  1. Thay vì xác định ID gốc trong mỗi lớp XML, tôi tự động tìm chế độ xem gốc bằng cách sử dụng android.R.id.content.
  2. Như @Mario Lenci nói, AdapterView không hỗ trợ removeAllViews, vì vậy tôi kiểm tra loại chế độ xem trước khi gọi removeAllViews().
  3. IMO, không nên gọi số System.gc() trong mọi cuộc gọi onDestroy (ví dụ: this answer), vì vậy tôi đã xóa điều đó.
  4. Tôi đã thực hiện phương thức tĩnh onDestroy mà tôi gọi từ onDestroy trong tất cả các lớp Hoạt động tùy chỉnh của mình.
  5. Tôi đã thêm một số bảo vệ và ghi nhật ký lỗi bổ sung.

Dưới đây là các mã:

public static void onDestroy(Activity activity) { 
     View rootView = null; 

     try {    
      rootView = ((ViewGroup) activity.findViewById(android.R.id.content)) 
        .getChildAt(0); 
     } catch (Exception e) { 
      Log.w("Cannot find root view to call unbindDrawables on", 
        activity); 
     } 

     if (rootView != null) { 
      Log.d("unbindDrawables", activity, rootView); 
      unbindDrawables(rootView); 
     } 
    } 

    /** 
     * Utility method to unbind drawables when an activity is destroyed. This 
     * ensures the drawables can be garbage collected. 
     */ 
    public static void unbindDrawables(View view) { 
     if (view.getBackground() != null) { 
      view.getBackground().setCallback(null); 
     } 

     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
       unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 

      try {     
       // AdapterView objects do not support the removeAllViews method 
       if (!(view instanceof AdapterView)) {    
        ((ViewGroup) view).removeAllViews(); 
       } 
      } catch (Exception e) { 
       Log.w("Ignore Exception in unbindDrawables", e); 
      } 
     } 
    } 
4

Thêm dòng mã này để Android Manifest file bên trong "ứng dụng" tag: - android: largeHeap = "true"

<application 
     android:theme="@android:style/Theme.NoTitleBar" 
     android:allowBackup="true" 
     android:largeHeap="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     > 
+0

Cảm ơn. Nó hoạt động :) –

Các vấn đề liên quan