[이 (CommonsWare가 지적한대로)이 답변의 전체 접근 방식은 2.3.x (진저 브레드)까지만 적용됩니다. Honeycomb 현재 비트 맵 데이터는 VM 힙에 할당됩니다.]
비트 맵 데이터는 VM 힙에 할당되지 않습니다. VM 힙 (작은 크기)에 대한 참조가 있지만 실제 데이터는 기본 Skia 그래픽 라이브러리에 의해 기본 힙에 할당됩니다.
불행히도 BitmapFactory.decode ...()의 정의에 따르면 이미지 데이터를 디코딩 할 수없는 경우 null을 반환하지만 Skia 구현 (Java 코드와 Skia 간의 JNI 아교)은 메시지 ("VM에서 xxxx 바이트를 할당 할 수 없습니다.")와 잘못된 메시지 (비트 맵 크기가 VM 예산 초과)로 OutOfMemory 예외가 발생합니다.
문제는 VM 힙에 없으며 오히려 원시 힙에 있습니다. Natïve 힙은 실행중인 응용 프로그램간에 공유되므로 사용 가능한 공간의 양은 실행중인 다른 응용 프로그램과 해당 비트 맵 사용에 따라 다릅니다. 그러나 BitmapFactory가 반환되지 않는다면 호출하기 전에 호출이 성공하는지 알아낼 방법이 필요합니다.
네이티브 힙의 크기를 모니터하는 루틴이 있습니다 (Debug 클래스 getNative 메소드 참조). 그러나 getNativeHeapFreeSize() 및 getNativeHeapSize()가 신뢰할 수 없다는 것을 발견했습니다. 따라서 많은 수의 비트 맵을 동적으로 만드는 내 응용 프로그램 중 하나에서 다음을 수행합니다.
네이티브 힙 크기는 플랫폼에 따라 다릅니다.따라서 시작시 허용되는 최대 VM 힙 크기를 확인하여 최대 허용 된 기본 힙 크기를 결정합니다. [마법의 숫자는 2.1 및 2.2에서 테스트에 의해 결정되었고, 다른 API 수준에 따라 달라질 수 있습니다.]
long mMaxVmHeap = Runtime.getRuntime().maxMemory()/1024;
long mMaxNativeHeap = 16*1024;
if (mMaxVmHeap == 16*1024)
mMaxNativeHeap = 16*1024;
else if (mMaxVmHeap == 24*1024)
mMaxNativeHeap = 24*1024;
else
Log.w(TAG, "Unrecognized VM heap size = " + mMaxVmHeap);
그런 다음 우리가 BitmapFactory를 호출해야 할 때마다 우리는 형식의 수표로 전화를 앞에. heapPad가) 기본 힙 크기의 보고서는 "소프트"사실 수 있도록하는 마법의 수이고 b)는 우리가 다른 응용 프로그램의 기본 힙에 약간의 공간을 남겨하려는
는
long sizeReqd = bitmapWidth * bitmapHeight * targetBpp/8;
long allocNativeHeap = Debug.getNativeHeapAllocatedSize();
if ((sizeReqd + allocNativeHeap + heapPad) >= mMaxNativeHeap)
{
// Do not call BitmapFactory…
}
참고. 우리는 현재 3 * 1024 * 1024 (즉, 3Mbytes) 패드로 실행 중입니다.
[this] (http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object/14731953#14731953) 도움이 될 수 있습니다! –