정상에서 IT를 외치다

[Android, OOM] 메모리릭과 OOM이란? 본문

안드로이드

[Android, OOM] 메모리릭과 OOM이란?

Black-Jin 2019. 3. 23. 11:57
반응형

 

안녕하세요. 블랙진입니다.

 

안드로이드 앱을 개발할 때는 제한된 메모리를 어떻게 사용해야 좋은 성능을 낼 수 있는지 항상 고민해야 합니다. 물론 JAVA에는 GC(Garbage Collection)을 통해 알아서 메모리를 관리해 주지만 능사는 아닙니다. 아무리 관리를 해준다 해도 개발자가 신경 쓰지 않으면 메모리릭과 OOM이 발생하기 마련 입니다. 이에 대해 정리하기 전에 GC가 어떻게 동작하는지를 알아야 더욱 이해하기 쉽습니다. 이는 설명이 잘되있는 블로그가 있어 링크로 남기겠습니다.

 

 

메모리릭과 ORM 이란?

 

메모리릭은 메모리 누수라고도 합니다. 어플리케이션이 사용이 끝난 메모리를 반환하지 않은 경우 멤모리 릭이 발생합니다. 이렇게 사용하지 않은 메모리 양이 계속 증가하게 되면 최악의 경우 Out Of Memory(OOM)를 발생시키고 어플리케이션이 강제 종료되면서 할당되었던 메모리가 시스템으로 회수됩니다.

 

 

메모리릭 발생하는 이유?

 

GC의 대상이 되지 않아 발생하게 됩니다. 

 

일반적으로 아래와 같은 경우 GC의 대상이됩니다.

 

1. 모든 객체 잠조가 null 인 경우

2. 객체가 블럭 안에서 생성되고 블럭이 종료된 경우

3. 부모 객체가 null 이 된 경우, 자식 객체는 자동적으로 GC 대상이 됩니다.

4. 객체가 Weak 참조만 가지고 있을 경우

5. 객체가 Soft 참조이지만 메모리 부족이 발생한 경우

 

 

메모리릭 사례

 

1. Activity Context 의 잘못된 사용

 

어플리케이션 Context 는 어플리케이션 자체의 생명주기 영향을 받습니다. 그러나 엑티비티의 Context 는 엑티비티의 라이프사이클과 함께 작동해 onDestory 와 함께 사라집니다. 이에 메모리 관리를 위해서는 뷰를 수정할 때는 엑티비티의 Context 를 사용하고 나머지 경우에는 어플리케이션의 Context 를 사용하는게 좋습니다. 이에 대한 예로는 Activity 에서 Drawable 변수를 static 생성한 후 new TextView(this) 를 통해 생성된 textVIew 와 연결합니다. 그러면 Activity 가 제거되어도 static 으로 선언된 drawable 이 textVIew 와 연결되어 있고 이는 Activity 를 참조하고 있기 때문에 GC의 대상이 안됩니다. 이에 관한 예시 및 설명 그리고 코드는 구글블로그에서 볼 수 있습니다.

 

번외) Context 란?

어플리케이션 정보를 가져올 수 있는 글로벌 인터페이스 입니다. 안드로이드 시스템 서비스에서 제공하는 다양한 API 를 호출할 수 있습니다.

 

2. inner Class 의 잘못된 사용

 

non static inner class 는 outer class 에 대한 참조를 가지지만 static inner class 는 outer 에 대한 참조를 가지지 않습니다. 이에 대한 예제 코드는 링크로 남기겠습니다.

 

정리 및 해결방법

 

1. Activity Context 대신 Application Context 사용을 더 고려하자

2. Activity Context 를 사용할 경우 Activity 생명주기와 싱크를 맞춰라

3. 만일 Activity에 Sub-Class 를 정의하여 사용한다면, sub-class 에서 상위 Activity 를 참조하는 경우를 되도록 만들지 마라.  대신 sub-class 를 static 으로 정의하고 해당 클래스가 Activity 와 WeakReference 를 갖도록 하라.

 

<참고자료>

구글 블로그

금광캐는 광부

메모리릭 사례

How to Leak a Context

반응형
Comments