2013-04-02 9 views
11

Obecnie tworzę aplikację, która przechodzi przez historię. Historia zawiera "sceny", które zawierają wiele plików JPEG i PNG, które są wyświetlane za pośrednictwem ImageViews. I stworzyć ImageView i dodać w nim do układu za pomocą następujących funkcji:Problem z bitmapowym systemem Android - Błąd: Brak pamięci w alokacji 8294416-bajtowej

private ImageView newImage(Show show) 
{ 
    ImageView iv = new ImageView(this); 
    String filePath = comin.generateFilePath(show); 
    Log.i(TAG, "newImage, filePath = " + filePath + " id = " + show.id); 
    WeakReference<Bitmap> bmp = new WeakReference<Bitmap>(scaleBitmap(filePath)); //added 4/1/13 
    //Bitmap bmp = scaleBitmap(filePath); 
    Log.i(TAG, "newImage, width = " + bmp.get().getWidth() + ", height = " + bmp.get().getHeight()); 
    iv.setImageBitmap(bmp.get()); 
    iv.setScaleType(ImageView.ScaleType.FIT_XY); 
    iv.setId(show.id); 

    //set visibility 
    if (show.visible) 
     iv.setVisibility(View.VISIBLE); 
    else 
     iv.setVisibility(View.INVISIBLE); 

    //set dimensions 
    int width = (app.getWidth() * show.dimX)/100; 
    int height = (app.getHeight() * show.dimY)/100; 
    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(width, height); 
    iv.setLayoutParams(rlp); 

    return iv; 
} 

Gdy scena jest ponad, ja potem jasno wszystkie ImageViews z wyjątkiem jednego, który nie ma obrazu, a jedynie służy do nasłuchiwania kontakcie wydarzenia.

private void clearScene(boolean clearTouch) 
{ 
    RelativeLayout parent = (RelativeLayout) findViewById(R.id.relative_layout); 
    logMemory("clearScene, START"); 

    int count = parent.getChildCount(); 
    for (int a = count - 1; a >= 0; a--) 
    { 
     int id = parent.getChildAt(a).getId(); 
     String message = "clearScene id = " + id + ", count = " + count + ", a = " + a; 
     if (id == TOUCH_VIEW_ID && !clearTouch) 
     { 
      message = message + ", ignore touch screen view"; 
     } 
     else 
     { 
      unbindView(parent.getChildAt(a)); 
      parent.getChildAt(a).clearAnimation(); 
      parent.removeView(parent.getChildAt(a)); 
      message = message + ", unbindView, clearAnimation, removeView"; 
     } 
     Log.i(TAG, message); 
     logMemory("clearScene, CLEARED VIEW"); 
    } 

    handler.removeCallbacksAndMessages(null); //stop any future scheduled tasks from triggering 
    logMemory("clearScene, BEFORE TRASH COLLECTOR"); 
    System.gc(); 
    logMemory("clearScene, AFTER TRASH COLLECTOR"); 
} 

Jak widać, wywoływana jest metoda unbindView(), aby spróbować usunąć wszelkie możliwe wycieki pamięci.

private void unbindView(View view) 
{ 
    String message = "unbindView, id = " + view.getId(); 
    try {view.setOnClickListener(null);} catch (Throwable mayHappen) {}; 
    try {view.setOnCreateContextMenuListener(null);} catch (Throwable mayHappen) {}; 
    try {view.setOnFocusChangeListener(null);} catch (Throwable mayHappen) {}; 
    try {view.setOnKeyListener(null);} catch (Throwable mayHappen) {}; 
    try {view.setOnLongClickListener(null);} catch (Throwable mayHappen) {}; 
    try {view.setOnClickListener(null);} catch (Throwable mayHappen) {}; 

    if (view.getBackground() != null) 
    { 
     message = message + ", setBackgroundCallback(null)"; 
     view.getBackground().setCallback(null); 
    } 

    if (view instanceof ImageView) 
    { 
     if (((ImageView)view).getDrawable() != null) 
     { 
      if (((ImageView)view).getDrawable() instanceof BitmapDrawable) 
      { 
       message = message + ", recycle bitmap"; 
       ((BitmapDrawable)((ImageView)view).getDrawable()).getBitmap().recycle(); 
      } 
      message = message + ", setDrawableCallback(null)"; 
      ((ImageView)view).getDrawable().setCallback(null); 
     } 
     message = message + ", setImageBitmap(null), setBackgroundDrawable(null)"; 
     ((ImageView) view).setImageBitmap(null); 
     ((ImageView) view).setBackgroundDrawable(null); 
    } 
    Log.i(TAG, message); 
} 

Gdy wszystkie ImageView są nieograniczone, uruchamiam garbage collector w funkcji clearScene.

*** EDYCJA (4/2/13) OK, po kilku badaniach i próbach i błędach, zmieniłem rejestrację pamięci. Oto odpowiednie metody:

W onResume() ustawię wartość logiczną na wartość true w zależności od wersji Androida (w celu określenia, czy używa ona pamięci natywnej lub Java dla bitmap), a następnie inicjalizuję wartość domyślną 0 dla stare wartości pamięci;

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

    if (android.os.Build.VERSION.SDK_INT >= 11) debugJavaMemory = true; 
    else debugNativeMemory = true; 
    availableJavaMemoryOld = 0; 
    availableNativeMemoryOld = 0; 
    dialogDebug(); 
} 

To jest moja funkcja logowania. Loguje się w zależności od tego, czy bieżąca wersja Androida używa pamięci rodzimej lub Java do przechowywania bitmap.

private void logMemory(String callingFunction) 
{ 
    if (debugJavaMemory) 
    { 
     long max = Runtime.getRuntime().maxMemory()/1024; 
     long used = Runtime.getRuntime().totalMemory()/1024; 
     long available = max - used; 
     long change = available - availableJavaMemoryOld; 
     if (availableJavaMemoryOld != 0) 
      Log.i(TAG_MEMORY, "jMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction); 
     availableJavaMemoryOld = available; 
    } 
    else if (debugNativeMemory) 
    { 
     long max = Debug.getNativeHeapSize()/1024; 
     long used = Debug.getNativeHeapAllocatedSize()/1024; 
     long available = max - used; 
     long change = available - availableNativeMemoryOld; 
     if (availableNativeMemoryOld != 0) 
      Log.i(TAG_MEMORY, "nMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction); 
     availableNativeMemoryOld = available; 
    } 
} 

Jeśli spojrzeć na moim dzienniku zbieram od emulatorze z systemem Android 2.3.3 (10), kolektor śmieci wydaje się być doskonale działa! Zauważyłem tylko, że Max Native Memory może się dynamicznie zwiększać !?

Legenda: M: (maks pamięci) U (stosowany pamięci), A (dostępnej pamięci), C (zmiana w dostępnej pamięci), funkcji, która wywołała Funkcja rejestru

04-03 02:34:20.758: I/MEMORY(1045): nMEM M:18336, U:13287, A:5049, C:-2549, loadScene, ADDED IMAGE b:0, s:0, id:0 
04-03 02:34:21.267: I/MEMORY(1045): nMEM M:21568, U:21391, A:177, C:-4872, loadScene, ADDED IMAGE b:0, s:0, id:1 
04-03 02:34:35.227: I/MEMORY(1045): nMEM M:21568, U:13288, A:8280, C:8103, clearScene, CLEARED VIEW id:1 
04-03 02:34:35.267: I/MEMORY(1045): nMEM M:21568, U:5184, A:16384, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:34:35.327: I/MEMORY(1045): nMEM M:21568, U:4977, A:16591, C:207, clearScene, AFTER TRASH COLLECTOR 
04-03 02:34:36.067: I/MEMORY(1045): nMEM M:21568, U:13082, A:8486, C:-8105, loadScene, ADDED IMAGE b:1, s:0, id:0 
04-03 02:34:47.177: I/MEMORY(1045): nMEM M:21568, U:4979, A:16589, C:8103, clearScene, CLEARED VIEW id:0 
04-03 02:34:47.277: I/MEMORY(1045): nMEM M:21568, U:4978, A:16590, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:34:47.997: I/MEMORY(1045): nMEM M:21568, U:13082, A:8486, C:-8104, loadScene, ADDED IMAGE b:1, s:1, id:0 
04-03 02:34:49.307: I/MEMORY(1045): nMEM M:26224, U:21186, A:5038, C:-3448, loadScene, ADDED IMAGE b:1, s:1, id:1 
04-03 02:34:50.597: I/MEMORY(1045): nMEM M:34328, U:29290, A:5038, C:0, loadScene, ADDED IMAGE b:1, s:1, id:2 
04-03 02:34:51.839: I/MEMORY(1045): nMEM M:42432, U:37395, A:5037, C:-1, loadScene, ADDED IMAGE b:1, s:1, id:3 
04-03 02:35:00.377: I/MEMORY(1045): nMEM M:42432, U:29293, A:13139, C:8102, clearScene, CLEARED VIEW id:3 
04-03 02:35:00.387: I/MEMORY(1045): nMEM M:42432, U:21189, A:21243, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:35:00.397: I/MEMORY(1045): nMEM M:42432, U:13085, A:29347, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:35:00.407: I/MEMORY(1045): nMEM M:42432, U:4982, A:37450, C:8103, clearScene, CLEARED VIEW id:0 
04-03 02:35:00.449: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:4, clearScene, AFTER TRASH COLLECTOR 
04-03 02:35:01.217: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8105, loadScene, ADDED IMAGE b:1, s:2, id:0 
04-03 02:35:23.458: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:35:23.508: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:35:24.777: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:3, id:0 
04-03 02:35:25.719: I/MEMORY(1045): nMEM M:42432, U:21186, A:21246, C:-8104, loadScene, ADDED IMAGE b:1, s:3, id:1 
04-03 02:35:26.457: I/MEMORY(1045): nMEM M:42432, U:29291, A:13141, C:-8105, loadScene, ADDED IMAGE b:1, s:3, id:2 
04-03 02:35:55.008: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:35:55.027: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:35:55.037: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:35:55.077: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:35:55.829: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8105, loadScene, ADDED IMAGE b:1, s:4, id:0 
04-03 02:35:56.427: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8104, loadScene, ADDED IMAGE b:1, s:4, id:1 
04-03 02:36:00.257: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:36:00.278: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:00.318: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:01.687: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8105, loadScene, ADDED IMAGE b:1, s:5, id:0 
04-03 02:36:06.437: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:06.487: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:07.777: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:6, id:0 
04-03 02:36:09.297: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:09.337: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:10.727: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:7, id:0 
04-03 02:36:20.947: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:20.987: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:22.367: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:8, id:0 
04-03 02:36:23.317: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8105, loadScene, ADDED IMAGE b:1, s:8, id:1 
04-03 02:36:23.887: I/MEMORY(1045): nMEM M:42432, U:29291, A:13141, C:-8104, loadScene, ADDED IMAGE b:1, s:8, id:2 
04-03 02:36:26.507: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:36:26.517: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:36:26.527: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:26.577: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:27.797: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8105, loadScene, ADDED IMAGE b:1, s:9, id:0 
04-03 02:36:29.248: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:29.287: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:1, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:30.547: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:10, id:0 
04-03 02:36:32.177: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:32.228: I/MEMORY(1045): nMEM M:42432, U:4978, A:37454, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:33.467: I/MEMORY(1045): nMEM M:42432, U:13082, A:29350, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:0 
04-03 02:36:33.977: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8105, loadScene, ADDED IMAGE b:1, s:11, id:1 
04-03 02:36:34.527: I/MEMORY(1045): nMEM M:42432, U:29291, A:13141, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:2 
04-03 02:36:35.058: I/MEMORY(1045): nMEM M:42432, U:37395, A:5037, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:3 
04-03 02:36:41.260: I/MEMORY(1045): nMEM M:42432, U:29291, A:13141, C:8104, clearScene, CLEARED VIEW id:3 
04-03 02:36:41.267: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:36:41.278: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:36:41.287: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:36:41.337: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:36:42.618: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:0, id:0 
04-03 02:37:00.550: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:37:00.587: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:37:01.817: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:1, id:0 
04-03 02:37:03.347: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:37:03.397: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:37:04.607: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:2, id:0 
04-03 02:37:05.258: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8104, loadScene, ADDED IMAGE b:2, s:2, id:1 
04-03 02:37:07.677: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:37:07.687: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:37:07.737: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:37:09.017: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:3, id:0 
04-03 02:37:10.327: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8104, loadScene, ADDED IMAGE b:2, s:3, id:1 
04-03 02:37:13.330: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:37:13.337: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:37:13.387: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:0, clearScene, AFTER TRASH COLLECTOR 
04-03 02:37:14.697: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:4, id:0 
04-03 02:37:16.037: I/MEMORY(1045): nMEM M:42432, U:21187, A:21245, C:-8104, loadScene, ADDED IMAGE b:2, s:4, id:1 
04-03 02:37:17.367: I/MEMORY(1045): nMEM M:42432, U:29292, A:13140, C:-8105, loadScene, ADDED IMAGE b:2, s:4, id:2 
04-03 02:37:19.087: I/MEMORY(1045): nMEM M:42432, U:37396, A:5036, C:-8104, loadScene, ADDED IMAGE b:2, s:4, id:3 
04-03 02:37:44.347: I/MEMORY(1045): nMEM M:42432, U:29293, A:13139, C:8103, clearScene, CLEARED VIEW id:3 
04-03 02:37:44.357: I/MEMORY(1045): nMEM M:42432, U:21189, A:21243, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:37:44.367: I/MEMORY(1045): nMEM M:42432, U:13085, A:29347, C:8104, clearScene, CLEARED VIEW id:1 
04-03 02:37:44.377: I/MEMORY(1045): nMEM M:42432, U:4981, A:37451, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:37:44.437: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:2, clearScene, AFTER TRASH COLLECTOR 
04-03 02:37:45.667: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:5, id:0 
04-03 02:37:46.917: I/MEMORY(1045): nMEM M:42432, U:21188, A:21244, C:-8105, loadScene, ADDED IMAGE b:2, s:5, id:1 
04-03 02:37:48.167: I/MEMORY(1045): nMEM M:42432, U:29292, A:13140, C:-8104, loadScene, ADDED IMAGE b:2, s:5, id:2 
04-03 02:37:49.807: I/MEMORY(1045): nMEM M:42432, U:37396, A:5036, C:-8104, loadScene, ADDED IMAGE b:2, s:5, id:3 
04-03 02:38:08.239: I/MEMORY(1045): nMEM M:42432, U:29293, A:13139, C:8103, clearScene, CLEARED VIEW id:3 
04-03 02:38:08.258: I/MEMORY(1045): nMEM M:42432, U:21189, A:21243, C:8104, clearScene, CLEARED VIEW id:2 
04-03 02:38:08.267: I/MEMORY(1045): nMEM M:42432, U:13086, A:29346, C:8103, clearScene, CLEARED VIEW id:1 
04-03 02:38:08.277: I/MEMORY(1045): nMEM M:42432, U:4982, A:37450, C:8104, clearScene, CLEARED VIEW id:0 
04-03 02:38:08.317: I/MEMORY(1045): nMEM M:42432, U:4979, A:37453, C:3, clearScene, AFTER TRASH COLLECTOR 
04-03 02:38:09.527: I/MEMORY(1045): nMEM M:42432, U:13083, A:29349, C:-8104, loadScene, ADDED IMAGE b:2, s:6, id:0 

Jak wspomniano , pamięć jest czyszczona po tym, jak ImageView jest niezwiązany!

Oto dziennik, który zebrałem z uszkodzonego Nexusa 7 z Androidem 17 (4.2). Naprawdę trudno zrozumieć, w jaki sposób pamięć jest tutaj wykorzystywana. To nigdy nie jest zgodne! Czasami pamięć nie jest przydzielana po załadowaniu ImageView. Czasami pamięć jest czyszczona tylko po załadowaniu nowego ImageView.

Legenda: M: (maks pamięci) U (stosowany pamięci), A (dostępnej pamięci), C (zmiana w dostępnej pamięci), funkcji, która wywołała Funkcja rejestru

04-02 22:37:05.866: I/MEMORY(15827): jMEM M:65536, U:21300, A:44236, C:0, loadScene, ADDED IMAGE b:0, s:0, id:0 
04-02 22:37:06.136: I/MEMORY(15827): jMEM M:65536, U:29444, A:36092, C:-8144, loadScene, ADDED IMAGE b:0, s:0, id:1 
04-02 22:37:19.806: I/MEMORY(15827): jMEM M:65536, U:29432, A:36104, C:12, clearScene, CLEARED VIEW id:1 
04-02 22:37:19.806: I/MEMORY(15827): jMEM M:65536, U:29432, A:36104, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:37:19.836: I/MEMORY(15827): jMEM M:65536, U:29432, A:36104, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:37:20.116: I/MEMORY(15827): jMEM M:65536, U:37536, A:28000, C:-8104, loadScene, ADDED IMAGE b:1, s:0, id:0 
04-02 22:37:28.456: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:4, clearScene, CLEARED VIEW id:0 
04-02 22:37:28.486: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:37:28.756: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, loadScene, ADDED IMAGE b:1, s:1, id:0 
04-02 22:37:29.226: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, loadScene, ADDED IMAGE b:1, s:1, id:1 
04-02 22:37:29.706: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:-8104, loadScene, ADDED IMAGE b:1, s:1, id:2 
04-02 22:37:30.156: I/MEMORY(15827): jMEM M:65536, U:53740, A:11796, C:-8104, loadScene, ADDED IMAGE b:1, s:1, id:3 
04-02 22:37:38.676: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:8, clearScene, CLEARED VIEW id:3 
04-02 22:37:38.676: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, clearScene, CLEARED VIEW id:2 
04-02 22:37:38.676: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:37:38.676: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:37:38.696: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:37:38.966: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, loadScene, ADDED IMAGE b:1, s:2, id:0 
04-02 22:37:48.156: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:37:48.216: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:16200, clearScene, AFTER TRASH COLLECTOR 
04-02 22:37:48.676: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, loadScene, ADDED IMAGE b:1, s:3, id:0 
04-02 22:37:49.256: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, loadScene, ADDED IMAGE b:1, s:3, id:1 
04-02 22:37:49.716: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:-8104, loadScene, ADDED IMAGE b:1, s:3, id:2 
04-02 22:38:07.426: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:4, clearScene, CLEARED VIEW id:2 
04-02 22:38:07.426: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:07.426: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:07.496: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:07.766: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, loadScene, ADDED IMAGE b:1, s:4, id:0 
04-02 22:38:08.096: I/MEMORY(15827): jMEM M:65536, U:53736, A:11800, C:-8104, loadScene, ADDED IMAGE b:1, s:4, id:1 
04-02 22:38:10.896: I/MEMORY(15827): jMEM M:65536, U:53736, A:11800, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:10.896: I/MEMORY(15827): jMEM M:65536, U:53736, A:11800, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:10.916: I/MEMORY(15827): jMEM M:65536, U:53736, A:11800, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:11.436: I/MEMORY(15827): jMEM M:65536, U:53736, A:11800, C:0, loadScene, ADDED IMAGE b:1, s:5, id:0 
04-02 22:38:19.356: I/MEMORY(15827): jMEM M:65536, U:53732, A:11804, C:4, clearScene, CLEARED VIEW id:0 
04-02 22:38:19.386: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:8100, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:19.866: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, loadScene, ADDED IMAGE b:1, s:6, id:0 
04-02 22:38:21.326: I/MEMORY(15827): jMEM M:65536, U:45632, A:19904, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:21.356: I/MEMORY(15827): jMEM M:65536, U:21300, A:44236, C:24332, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:21.906: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:-8104, loadScene, ADDED IMAGE b:1, s:7, id:0 
04-02 22:38:24.376: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:24.406: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:24.916: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, loadScene, ADDED IMAGE b:1, s:8, id:0 
04-02 22:38:25.496: I/MEMORY(15827): jMEM M:65536, U:37548, A:27988, C:-8144, loadScene, ADDED IMAGE b:1, s:8, id:1 
04-02 22:38:25.796: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:-8104, loadScene, ADDED IMAGE b:1, s:8, id:2 
04-02 22:38:28.356: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, clearScene, CLEARED VIEW id:2 
04-02 22:38:28.356: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:28.356: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:28.376: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:28.846: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, loadScene, ADDED IMAGE b:1, s:9, id:0 
04-02 22:38:29.926: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:29.956: I/MEMORY(15827): jMEM M:65536, U:29400, A:36136, C:16252, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:30.416: I/MEMORY(15827): jMEM M:65536, U:29400, A:36136, C:0, loadScene, ADDED IMAGE b:1, s:10, id:0 
04-02 22:38:31.446: I/MEMORY(15827): jMEM M:65536, U:29400, A:36136, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:31.476: I/MEMORY(15827): jMEM M:65536, U:21300, A:44236, C:8100, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:31.966: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:0 
04-02 22:38:32.226: I/MEMORY(15827): jMEM M:65536, U:37548, A:27988, C:-8144, loadScene, ADDED IMAGE b:1, s:11, id:1 
04-02 22:38:32.526: I/MEMORY(15827): jMEM M:65536, U:45652, A:19884, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:2 
04-02 22:38:32.816: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:-8104, loadScene, ADDED IMAGE b:1, s:11, id:3 
04-02 22:38:34.396: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, CLEARED VIEW id:3 
04-02 22:38:34.396: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, CLEARED VIEW id:2 
04-02 22:38:34.396: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:34.396: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:34.426: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:34.886: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, loadScene, ADDED IMAGE b:2, s:0, id:0 
04-02 22:38:35.776: I/MEMORY(15827): jMEM M:65536, U:53756, A:11780, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:35.816: I/MEMORY(15827): jMEM M:65536, U:21300, A:44236, C:32456, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:36.256: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:-8104, loadScene, ADDED IMAGE b:2, s:1, id:0 
04-02 22:38:36.976: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:37.006: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:37.436: I/MEMORY(15827): jMEM M:65536, U:29404, A:36132, C:0, loadScene, ADDED IMAGE b:2, s:2, id:0 
04-02 22:38:37.816: I/MEMORY(15827): jMEM M:65536, U:37548, A:27988, C:-8144, loadScene, ADDED IMAGE b:2, s:2, id:1 
04-02 22:38:44.986: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:16, clearScene, CLEARED VIEW id:1 
04-02 22:38:44.986: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:45.016: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:45.496: I/MEMORY(15827): jMEM M:65536, U:37532, A:28004, C:0, loadScene, ADDED IMAGE b:2, s:3, id:0 
04-02 22:38:45.996: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:-8104, loadScene, ADDED IMAGE b:2, s:3, id:1 
04-02 22:38:48.306: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:48.306: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:48.336: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:48.846: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:0, loadScene, ADDED IMAGE b:2, s:4, id:0 
04-02 22:38:49.326: I/MEMORY(15827): jMEM M:65536, U:45636, A:19900, C:0, loadScene, ADDED IMAGE b:2, s:4, id:1 
04-02 22:38:49.856: I/MEMORY(15827): jMEM M:65536, U:53740, A:11796, C:-8104, loadScene, ADDED IMAGE b:2, s:4, id:2 
04-02 22:38:50.386: I/MEMORY(15827): jMEM M:65536, U:61844, A:3692, C:-8104, loadScene, ADDED IMAGE b:2, s:4, id:3 
04-02 22:38:59.486: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:12, clearScene, CLEARED VIEW id:3 
04-02 22:38:59.486: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, clearScene, CLEARED VIEW id:2 
04-02 22:38:59.486: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, clearScene, CLEARED VIEW id:1 
04-02 22:38:59.486: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, clearScene, CLEARED VIEW id:0 
04-02 22:38:59.516: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, clearScene, AFTER TRASH COLLECTOR 
04-02 22:38:59.936: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, loadScene, ADDED IMAGE b:2, s:5, id:0 
04-02 22:39:00.356: I/MEMORY(15827): jMEM M:65536, U:61832, A:3704, C:0, loadScene, ADDED IMAGE b:2, s:5, id:1 

I wcześniej przeszli szkolenia „Wyświetlanie bitmapy Skutecznie” w
http://developer.android.com/training/displaying-bitmaps/index.html

mam również poprzez następujące pytania StackOverflow:
Recycle ImageView's Bitmap
ImageView: automatically recycle bitmap if ImageView is not visible (within ScrollView)
android - out of memory exception when creating bitmap
Bitmap decodeStream OutOfMemory Exception
Detect application heap size in Android
android createBitmap OOM when ((freeMemory > bitmapSize) && (nativeFreeHeap < bitmap size))
android 495KB image taking 10MB of Heap size
Android ImageView setImageBitmap
Android Memory Leak solution
Android custom view Bitmap memory leak

I wiele wiele więcej artykułów w całej sieci!

Aby wyjaśnić, to zdarza się tylko w moim Nexusie 7. Nie doświadczyłem problemu na moim emulatorze lub moim Galaxy Nexusie. Myślę, że może to wynikać z faktu, że skaluję obrazy.

Proszę mi pomóc wykryć, gdzie jest wyciek pamięci!

*** EDYCJA (4/2/13) Proszę mi pomóc ustalić, dlaczego logi z emulatora z Androidem 10 (2.3.3) pokazują system alokujący pamięć i śmieci, a następnie czyszczący dokładnie tak, jak powinien, i logi z mojego Nexusa 7 z Androidem 17 (4.2) pokazują, że system przydziela pamięć i pamięć czyszczącą do odśmiecacza najwyraźniej losowo?

+0

+1 za badania. Ale czy ten wyjątek pojawia się tylko na emulatorze, czy jest wyświetlany również na urządzeniach? – Nezam

+0

Przepraszam, zaktualizuję pytanie, mam problem tylko na moim Nexusie 7. Mój galaxy nexus i emulator nie wydają się mieć problemu. Myślę, że to dlatego, że skaluję obrazy. – sngreco

+1

Słaba referencja może być nieskuteczna w bitmapie, ponieważ bitmapa wygląda na małą dla gc. (I generalnie nigdy nie powinno się 'robićAnything (bmp.get())' z tego powodu, że WeakReference może zostać zwolniony.) – 18446744073709551615

Odpowiedz

4

Nie byłem w stanie określić, dlaczego alokacja i gromadzenie pamięci różnią się między różnymi platformami, ale udało mi się złagodzić problem i uniemożliwić awarię aplikacji na dowolnej platformie poprzez skalowanie obrazów w celu dopasowania do dostępnej pamięci.

Ta pierwsza funkcja określa, gdzie jest przechowywana pamięć bitmapy (natywna lub Java), a następnie oblicza pozostałą dostępną pamięć (w KB).

private long calcAvailableMemory() 
{ 
    long value = Runtime.getRuntime().maxMemory(); 
    String type = ""; 
    if (android.os.Build.VERSION.SDK_INT >= 11) 
    { 
     value = value/1024) - (Runtime.getRuntime().totalMemory()/1024); 
     type = "JAVA"; 
    } 
    else 
    { 
     value = value/1024) - (Debug.getNativeHeapAllocatedSize()/1024); 
     type = "NATIVE"; 
    } 
    Log.i(TAG, "calcAvailableMemory, size = " + value + ", type = " + type); 
    return value; 
} 

Ta druga funkcja tworzy widok obrazu, który można dołączyć do układu. Obiekt Show zawiera różne zmienne potrzebne do zainicjowania ImageView, takie jak wymiary i ścieżka itd. Długa maxImageMemory pochodzi z pierwszej funkcji, a następnie jest podzielona przez liczbę widoków, które dołączam do układu, dając mi maksymalną ilość pamięci do przydzielenia każdej bitmapy.

private ImageView newImage(Show show, long maxImageMemory) 
{ 
    ImageView iv = new ImageView(this); 
    String filePath = comin.generateFilePath(show); 
    Bitmap bmp = scaleBitmap(filePath, maxImageMemory); 
    Log.i(TAG, "newImage, id:" + show.id + ", file:" + filePath + ", x:" + bmp.getWidth() + ", y:" + bmp.getHeight()); 
    iv.setImageBitmap(bmp); 
    iv.setScaleType(ImageView.ScaleType.FIT_XY); 
    iv.setId(show.id); 

    //set visibility 
    if (show.visible) 
     iv.setVisibility(View.VISIBLE); 
    else 
     iv.setVisibility(View.INVISIBLE); 

    //set dimensions 
    int width = (app.getWidth() * show.dimX)/100; 
    int height = (app.getHeight() * show.dimY)/100; 
    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(width, height); 
    iv.setLayoutParams(rlp); 

    return iv; 
} 

Trzeci funkcja skaluje mapę bitową, która zostanie załadowany do ImageView tworzona w funkcji 2. pętla jest najważniejsze, to znaczy, gdzie zwiększenie wielkości próbki, aż potrzebne pamięci dla mapy bitowej mniej niż maksymalna dostępna pamięć.

private Bitmap scaleBitmap(String path, long maxImageMemory) 
{ 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(path, options); 

    int sample = 1; 
    //Scale image to screen resolution 
    if (options.outHeight > app.getHeight() || options.outWidth > app.getWidth()) 
    { 
     int heightRatio = Math.round((float) options.outHeight/(float) app.getHeight()); 
     int widthRatio = Math.round((float) options.outWidth/(float) app.getWidth()); 
     sample = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 

    //Scale image to stay within memory limitations 
    while (calcBitmapSize(options.outWidth, options.outHeight, sample) > maxImageMemory) 
    { 
     sample++; 
    } 

    options.inSampleSize = sample; 
    options.inPurgeable = true; 
    options.inInputShareable = true; 
    options.inJustDecodeBounds = false; 

    Log.i(TAG, "scaleBitmap, scaleSample = " + sample); 
    return BitmapFactory.decodeFile(path, options); 
} 

Czwarte oblicza ilość pamięci wymaganej przez mapę bitową, w zależności od oryginalnej rozdzielczości, a także proponowany wielkości próbki.

private long calcBitmapSize(int width, int height, int sample) 
{ 
    long value = ((width/sample) * (height/sample) * 4)/1024; 
    Log.i(TAG, "calcBitmapSize, size = " + value); 
    return value; 
} 

Wreszcie opracowałem tę funkcję, aby pomóc w rozwiązywaniu wszystkich tych problemów z pamięcią. Loguje wykorzystanie pamięci w zależności od wersji Androida.

private void logMemory(String callingFunction) 
{ 
    long max = Runtime.getRuntime().maxMemory()/1024; 

    if (debugJavaMemory) 
    { 
     long used = Runtime.getRuntime().totalMemory()/1024; 
     long available = max - used; 
     long change = available - availableJavaMemoryOld; 
     if (availableJavaMemoryOld != 0) 
      Log.i(TAG_MEMORY, "jMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction); 
     availableJavaMemoryOld = available; 
    } 
    else if (debugNativeMemory) 
    { 
     long used = Debug.getNativeHeapAllocatedSize()/1024; 
     long available = max - used; 
     long change = available - availableNativeMemoryOld; 
     if (availableNativeMemoryOld != 0) 
      Log.i(TAG_MEMORY, "nMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction); 
     availableNativeMemoryOld = available; 
    } 
} 
1

miałem ten problem kilka miesięcy temu, spróbować, może pomóc:

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 8; 
Bitmap bitmap = BitmapFactory.decodeStream(fis, null, options); 
+0

Dziękuję za komentarz, ale obecnie mam funkcję dynamicznego próbkowania w dół, którą udostępniłem dzięki szkoleniom Android pod adresem http://developer.android.com/training/displaying-bitmaps/index.html Funkcja kończy się zwrotem sampleSize o wartości 1, ponieważ rozdzielczość pasuje do obrazu. Każdy obraz wydaje się zużywać około 8 MB pamięci (jak widać w dziennikach). Jeśli jedna scena ma tylko 4 obrazy, będzie to całkowita suma 32 MB lub około połowy dostępnej pamięci. – sngreco

0

Ten link może pomóc http://developer.android.com/training/displaying-bitmaps/load-bitmap.html Ten problem pojawia się również, gdy odkształcalne nie jest dostępny w drawable- xhdpi folder dla dużych telefonów komórkowych 720x1280. Sprawdź, czy używane przez Ciebie wyciągi znajdują się we właściwym folderze do rysowania.

+0

Dziękuję za komentarz, ale już przeszedłem przez to szkolenie. Aplikacja jest przeznaczona do ładowania obrazów z karty SD. Wyjaśnij swoje rozumowanie, że folder, w którym przechowujesz swój obraz, może zmniejszyć wykorzystanie pamięci lub zwolnić pamięć w razie potrzeby. – sngreco

+0

Niech ta odpowiedź rozwiąże Twoje zapytanie. Ten problem napotkałem i rozwiązałem w ten sposób, a teraz działa on prawidłowo. http://stackoverflow.com/questions/15394329/java-lang-outofmemoryerror-appears-after-sherlockactionbar-was-added/15395218#15395218 –

Powiązane problemy