티스토리 뷰

안녕하세요 박스여우입니다. 최근 언론사의 웹사이트와 앱을 제작중인데요, 언론사 애플리케이션 특성상 기사마다 이미지가 반드시 하나쯤은 있고, 그 기사들과 이미지들을 불러와 화면에 뿌려줘야 합니다.


하지만, 많은 이미지를 다루다 보니 [dalvikvm-heap: Out of memory on a 772812-byte allocation] 요런 에러, Out Of Memory - OOM이 발생하더군요



메모리 정리?


원인은 Android 상에서 제공되는 메모리(heap)는 정해저 있지만, 제가 많은 이미지를 사용한 관계로 메모리가 부족한 상황이 발생한 것입니다. 이 때, 메모리를 정리한답시고 사용하지 않는 객체에 null을 지정해 준다고 한들 해당 객체의 메모리가 정리되는게 아니고 정리될 후보가 되는것 입니다.


이 대신 Bitmap을 모두 사용한 뒤에는 bitmap.recycle()을 통해 메모리를 바로바로 해제할 수 있습니다.



 이미지 크기문제!


하지만 저의경우는 url로 부터 이미지를 다운받아 ImageView에 그려주게 되는데, 받아오는 이미지가 너무 큰게 원인이되어 OOM이 발생하였습니다. 제가 기사로부터 이미지를 얻어오는 소스는 다음과 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView imageView;
 
    public DownloadImageTask(ImageView imageView) {
        this.imageView= imageView;
    }
 
    protected Bitmap doInBackground(String... urls) {
        String urlStr = urls[0];
        Bitmap image = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream in = connection.getInputStream();
            image = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;
    }
 
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }
}
cs


전달받은 이미지 URL을 받고 URLConnection을 통해 inputStream을 열어 BitmapFactory를 이용해 최종적으로 Bitmap 이미지로 만들게 됩니다.


하지만, 위와같은 코드를 이용하여 많은 이미지를 다루게 되면 저처럼 OOM이 발생하게 됩니다. 이미지 사이가 어떻든 그 크기 그대로 받아오게 되기 때문이죠.


받아오는 이미지의 용량을 줄이기 위해 BitmapFactory.Options를 통해 이미지의 사이즈를 줄여서 받아올 수 있습니다(비록 해상도가 낮아지긴 하지만..) 아래는 BitmapFactory Option을 적용한 코드 입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView imageView;
 
    public DownloadImageTask(ImageView imageView) {
        this.imageView= imageView;
    }
 
    protected Bitmap doInBackground(String... urls) {
        String urlStr = urls[0];
        Bitmap image = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream in = connection.getInputStream();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize=2;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;
    }
 
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }
}
cs


inSampleSize=2; 옵션에서 이미지의 크기를 1/2배 줄이게 됩니다. 3을 주게 되면 1/3배가 되는것입니다. 이때 옵션을 짝수로 주면 연산이 더 빨라진다고 합니다...



 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함