728x90

안드로이드는 모바일 디바이스에서 동작하기 때문에 제한된 메모리 용량을 지녀, 누수(leak)가 많이 발생하면 사용 가능한 메모리가 부족하게 된다.

앱에 메모리 누수가 있는 경우, 객체는 메모리에서 반환될 수 없다.
결과적으로 안드로이드 시스템은 더 많은 메모리를 요청한다. 그러나 한계가 있다.
결국 시스템은 앱에 더 많은 메모리를 할당하는 것을 거부한다. 이렇게 되면 앱은 메모리 부족으로 인해 강제 종료된다.


strong/weak reference
자바의 garbage collector는 더 이상 참조되지 않는 객체를 자동으로 수거하여 프로그래머가 직접 메모리를 관리하지 않아도 되도록 해준다. 하지만 모든 경우에 대해 garbage collector가 깨끗하게 사용하지 않는 객체들을 정리해주는 것은 아니다. 때로는 참조가 계속 남아있는 경우가 있을 수 있고 이런 경우에 객체는 수거되지 않고 memory leak으로 이어질 수 있다. 이와 같이 참조를 부주의하게 사용하여 발생할 수 있는 memory leak현상을 막기 위해서는 객체에 대한 참조를 유연하게 다루어 필요하지 않은 객체들이 수거될 수 있도록 해야한다.


GC(Garbage collector)는 참조 카운트가 0인 인스턴스들 즉, unReachable에 대한 객체에 대해서만 메모리를 회수한다.
만약 Activity 인스턴스가 Heap 루트로부터 어떤 strong reference에 묶여있는 경우라면, GC(Garbage collector)는 이를 메모리에서 제거할 수 없고, 해당 인스턴스는 leaked Activity 오브젝트가 된다.


메모리 누수가 발생하는 상황

- 프로세스-앱의 상태와 관계없이 글로벌 스태틱 오브젝트가 존재하고 액티비티의 참조들의 체인을 유지할 때

- 쓰레드-액티비티 생명주기를 무시하고 strong reference가 남아있을 때

- AsyncTask 를 선언하고 인스턴스화하는 것을 액티비티 내 익명 클래스에서 진행할 경우,

  Activity가 종료되어도(destroy) 백그라운드에서 계속 존재하게 되며 GC가 수거하지 못한다.

- AsyncTask를 생성했던 Activity가 먼저 destroy되는 경우(다른 UI로 전환) 메모리 릭이 발생할 수 있다.

  이미 자신을 실행시켰던 Activity가 존재하지 않는데 AsyncTask가 UI 처리같은 걸을 요구하면

  메모리상에 존재하지 않는 것을 참조하게 되어 메모리릭이 발생한다.


메모리 누수를 피하는 법

출처 : https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html

- GC(garbage collector)가 메모리 누수에 대한 보험은 아니다

- 라이프 사이클을 제어할 수 없다면, Activity 내에서 non-static inner classes 를 피하라.

- AsyncTask는 doInBackground 메소드만 백그라운드 스레드에서 실행되며, 나머지는 메인 스레드에서 실행된다.
백그라운드 작업시간이 긴 경우에는 UI 에서 실행중임을 알 수 있도록 ProgressBar 를 보여줘서
Activity 가 전환되지 않도록 하라.

- context-activity 대신 context-application 을 사용하라.

  Activity Context의 Reference 생명 주기는 반드시 Activity 생명 주기와 동일해야 한다.

  뷰를 수정하거나 할때는 Activity Context를 나머지 경우에는 Application Context를 사용하라.

  Context 에는 2가지 종류가 있다. Application context, Activity context ==> http://dev.youngkyu.kr/36 참조


static 변수 사용을 지양하라.

- static은 객체 지향적이지 않다.
- 지나치게 많은 static 변수를 사용하게 되면 이들로부터 메모리 회수를 할 수 없어서 가상머신이 메모리 부족을 겪을 수 있다.
- static 변수는 프로그램이 실행되고 있는 내내 살아있게 된다.
- 하나의 인스턴스로 생성하게 되면, 호출을 시키게 되면 그 함수 호출이 끝난 후 인스턴스는 소멸된다.
  훨씬 메모리를 절약하게 된다.
- static 메서드는 interface를 구현하는데 사용될 수 없다.
- 여러개의 인스턴스를 만드는 것을 피하고 싶다면 싱글톤 디자인 패턴을 이용하는 것이 훌륭한 대안이 될 수 있다.


bitmap 메모리 누수 관련 글

http://www.androidpub.com/1282821



Context 메모리 누수 피하는 방법 관련 글

http://blog.naver.com/huewu/110082062273



참고 사이트

http://www.kmshack.kr/2017/03/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98-%ED%8C%A8%ED%84%B4/


안드로이드 앱이 메모리 누수(Leak)를 만드는 8가지 방법

http://sjava.net/2016/05/%EB%B2%88%EC%97%AD-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%B1%EC%9D%B4-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98leak%EB%A5%BC-%EB%A7%8C%EB%93%9C%EB%8A%94-8%EA%B0%80%EC%A7%80/



블로그 이미지

Link2Me

,