biemap 메모리 오버플로우

2723 단어 bitmap
자세히 보기
안드로이드 시스템의 핸드폰은 시스템 밑에 메모리의 상한치를 지정했다. 대부분의 핸드폰의 절약치는 16MB이다. 그러나 일부 고사양 기종은 24MB이다. 그래서 우리 프로그램은 메모리 공간을 신청할 때 메모리 공간에 성공적으로 신청할 수 있도록 현재 분배된 메모리와 현재 분배해야 하는 메모리 값의 총 크기가 현재 쌓인 최대 메모리 값을 초과하지 않도록 해야 한다.메모리 관리는 외부 메모리를 현재 무더기의 일부로 간주한다. 즉, 비트맵 대상은 창고의 인용을 통해 무더기의 비트맵 대상을 가리키고, 무더기의 비트맵 대상은 외부에 저장된 네이티브 이미지, 즉 실제적으로 사용된 바이트 그룹byte[]로 저장된 비트맵 정보에 대응하기 때문에 디코딩된 비트맵의 총 크기는 8M을 초과할 수 없다.
이런 문제를 해결하는 가장 근본적이고 가장 효과적인 방법은bitmap을 사용한 후에bitmap 대상의recycle() 방법을 호출하여 다음에 사용하기 편리하도록 차지하는 메모리를 방출하는 것이다.
다음은 인터넷에서 자주 사용하는 최적화 방법들이지만 기본적으로 본질적으로 문제를 해결할 수 없다.
1. 시스템의 최소 스택 크기를 설정합니다.
int newSize = 4 * 1024 * 1024 ; // 4MB  
VMRuntime.getRuntime().setMinimumHeapSize(newSize);  
VMRuntime.getRuntime().setTargetHeapUtilization(0.75); //  75%  

추가 설명: 무더기(HEAP)는 VM에서 메모리를 가장 많이 사용하는 부분으로 보통 동적으로 분배된다.무더기의 크기는 고정불변한 것이 아니다. 무더기의 실제 이용률이 설정된 값에서 벗어날 때 가상 기회는 GC에서 무더기의 크기를 조정하여 실제 점용률을 백분율로 끌어올린다.예를 들어 초기의 HEAP는 4M 크기로 4M의 공간이 75%를 초과할 때 다시 8M 크기로 분배한다.8M이 75%를 넘으면 분배 더미는 16m가 된다.거꾸로 16m의 퇴적 이용이 30% 미만일 때 크기를 8m로 줄인다.더미의 크기를 재설정하는데 특히 압축은 일반적으로 메모리의 복사와 관련되기 때문에 더미의 크기를 변경하는 것은 효율에 좋지 않은 영향을 미친다.
2. 그림의 크기를 조절한다
BitmapFactory.Options options = new BitmapFactory.Options();  
options.inSampleSize = 2; // ,   
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/a.jpg",options); 
// bitmap = BitmapFactory.decodeStream(new FileInputStream(file),null,options);

보충 설명: 이런 방법은 그림에 대해 축소 처리를 했을 뿐 그림의 해상도를 낮추었기 때문에 그림의 질을 확보해야 하는 응용에서 취할 수 없다.
3.
BitmapFactory.Options options = new BitmapFactory.Options();  
options.inTempStorage = new byte[1024*1024*5]; //5MB   
Bitmap bm = BitmapFactory.decodeFile("/mnt/sdcard/a.jpg",options);  

추가 설명: Bitmap을 만드는 C++ 기본 코드에서 BitmapFactory.cpp의 처리 논리를 보면 옵션이null이 아니라면 옵션에 설정된 매개 변수를 우선적으로 처리할 것입니다. 현재 옵션의 inTempStorage가 1024*1024*4(4M) 크기라고 가정하고 이미지를 디코딩할 때마다 이 옵션을 참수로 사용하면 프로그램이 미리 실패할 수 있습니다. 테스트를 통해 1.03M 크기의 그림을 디코딩하면만약에 옵션 파라미터를 사용하지 않고 디코딩을 하면 네 번, 즉 네 번의 메모리를 정상적으로 디코딩할 수 있지만 옵션을 사용하면 메모리 넘침 오류가 발생하여 두 번만 정상적으로 디코딩할 수 있다.옵션스 클래스에는 옵션스를 전송할 때 임시로 사용할 메모리 크기를 지정하면 안드로이드는 기본적으로 지정한 메모리 크기를 먼저 신청합니다. 신청에 실패하면 메모리 넘침 오류를 먼저 던집니다.메모리 크기를 지정하지 않으면 시스템이 자동으로 계산합니다. 현재 3M 공간 크기가 남아 있고 디코딩이 2M 크기만 있으면 디코딩에 성공할 수 있으며, inTempStorage 크기를 4M으로 설정하면 메모리 넘침 오류가 발생합니다.따라서 Options의 inTempStorage 크기를 설정해도 큰 이미지 디코딩의 메모리 넘침 문제를 근본적으로 해결할 수 없다.
한 마디로android 개발을 할 때 메모리 넘침이 발생하는 것은 시스템의 밑바닥 제한에 속한다. 디코딩에 필요한 메모리가 시스템이 분배할 수 있는 최대 메모리 값을 초과하면 메모리 넘침 오류가 반드시 발생할 것이다.

좋은 웹페이지 즐겨찾기