다음과 같은 비트 맵 객체에 이미지를로드했다고 가정 해 보겠습니다.
Bitmap myBitmap = BitmapFactory.decodeFile(myFile);
이제 다음과 같은 다른 비트 맵을로드하면 어떻게 되나요?
myBitmap = BitmapFactory.decodeFile(myFile2);
첫 번째 myBitmap은 어떻게 되나요? 가비지 수집을 받거나 다른 비트 맵을로드하기 전에 수동으로 가비지 수집해야합니까? myBitmap.recycle()
?
또한 큰 이미지를로드하고 도중에 재활용하면서 차례로 표시하는 더 좋은 방법이 있습니까?
답변
첫 번째 비트 맵은 두 번째 비트 맵 을 디코딩 할 때 가비지 수집 되지 않습니다 . Garbage Collector 는 나중에 결정할 때마다이를 수행합니다. 최대한 빨리 메모리를 확보 recycle()
하려면 두 번째 비트 맵을 디코딩하기 직전에 호출해야합니다 .
정말 큰 이미지를로드하려면 리샘플링해야합니다. 다음은 예입니다. 이미지를 Bitmap 객체로로드하는 동안 이상한 메모리 부족 문제가 발생했습니다 .
답변
문제는 이것이 있다고 생각합니다. Android의 Honeycomb 이전 버전에서 실제 원시 비트 맵 데이터는 VM 메모리에 저장되지 않고 대신 기본 메모리에 저장됩니다. 이 네이티브 메모리 는 해당 자바 Bitmap
객체가 GC 일 때 해제됩니다 .
그러나 네이티브 메모리가 부족하면 dalvik GC가 트리거되지 않으므로 앱에서 자바 메모리를 거의 사용하지 않을 수 있으므로 dalvik GC가 호출되지 않지만 비트 맵에 많은 네이티브 메모리를 사용합니다. 결국 OOM 오류가 발생합니다.
적어도 그것은 내 추측이다. 고맙게도 Honeycomb 이상에서는 모든 비트 맵 데이터가 VM에 저장되므로 전혀 사용할 필요가 없습니다 recycle()
. 그러나 수백만 명의 사용자 (조각화 가 주먹을 흔드는 경우 )의 경우 recycle()
가능한 한 사용해야 합니다 (엄청난 번거 로움). 또는 대신 GC를 호출 할 수 있습니다.
답변
다음 이미지를로드하기 전에 myBitmap.recycle ()을 호출해야합니다.
myFile의 소스에 따라 (예 : 원본 크기를 제어 할 수없는 경우) 단순히 임의의 숫자를 리샘플링하는 대신 이미지를로드 할 때 이미지를 디스플레이 크기에 맞게 조정해야합니다.
if (myBitmap != null) {
myBitmap.recycle();
myBitmap = null;
}
Bitmap original = BitmapFactory.decodeFile(myFile);
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true);
if (original != myBitmap)
original.recycle();
original = null;
내 활동을 시작할 때 초기화 한 정적에 displayWidth 및 displayHeight를 캐시합니다.
Display display = getWindowManager().getDefaultDisplay();
displayWidth = display.getWidth();
displayHeight = display.getHeight();
답변
비트 맵이 메모리에로드되면 실제로 두 부분의 데이터로 만들어졌습니다. 첫 번째 부분은 비트 맵에 대한 정보를 포함하고 다른 부분은 비트 맵의 픽셀에 대한 정보를 포함합니다 (바이트 배열로 구성됨). 첫 번째 부분은 Java 사용 메모리에 있고 두 번째 부분은 C ++ 사용 메모리에 있습니다. 서로의 메모리를 직접 사용할 수 있습니다. Bitmap.recycle ()은 C ++의 메모리를 해제하는 데 사용됩니다. 그렇게 만하면 GC는 Java의 일부를 수집하고 C의 메모리는 항상 사용됩니다.
답변
Timmmm이 옳았습니다.
에 따르면 :
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
또한 Android 3.0 (API 레벨 11) 이전에는 비트 맵의 백업 데이터가 예측 가능한 방식으로 출시되지 않은 네이티브 메모리에 저장되어 잠재적으로 애플리케이션이 일시적으로 메모리 제한을 초과하고 충돌을 일으킬 수 있습니다.