[ Intro.. ]

ViewModel 내부에서 Context를 써먹을 상황이 있었다. (DB, SharedPrefernces.. 등)
저렇게 변수를 만들고 ViewModel 에서 Activity의 Context를 참조한 후 context 값을 넣어 활용하려 했으나,
갑작스레 형광팬이 그어졌다..!!!!
읽어보니 메모리 누수가 발생한다는 경고문 이였다..!
최근 진행 프로젝트와 관련하여 메모리 누수로 인해,
앱이 무거워지고 느려지며 버벅이는 현상을 체험하고있던 나는 이게 뭔지 걱정이 되었다..ㅜㅜ
메모리 누수 방지를 위해
Context가 무엇인지 이번포스팅에서 설명하고,
위 문제를 극복하는 방법을 다음 포스팅에서 정리해보려 한다!!
[ Context 란? ]
공식 문서를 정리해보면 다음과 같다.
1. 어플리케이션 환경에 대한 전역 정보의 Interface
2. Android 시스템에서 구현을 제공하는 추상 클래스
3. 어플리케이션 별 리소스와 클래스 접근 허용해주는 역할
( Activity 시작, Intent, Toast, Dialog, DB접근, SharedPreferences, BroadCating 등)
이해한대로 쉽게 정리해보면,
1. 현재 앱 상태를 나타내는 인터페이스
2. 시스템 정보에 접근을 가능하게 해주는 권한..? 같은 역할
이라 정리할 수 있다.
그리고 우리가 Activity에서 Context가 필요한 부분에 this로 Context를 넣어줬는데
Activity 상속을 따라가보면,
AppCompatActivity > FragmentActivity > ComponentActivity > androidx.core.app.ComponentActivity > Activity > ContextThemeWrapper > ContextWrapper > Context
결국 Activity가 Context를 상속받고 있기 때문에 Context 참조가 가능한 것이였다.
[ Context 종류가 두 개 라는데?? ]
Context를 공부하다보니 Application Context와 Activity Context를 찾을 수 있었다.
결과부터 말하자면..
이름처럼 Application Context가 더 큰 범위긴 하나, 이 둘을 구별해서 써야지 메모리 누수를 피할 수 있다.
Application Context.
- Application 사이클을 따라가는 글로벌 Context.
(Application의 시작부터 끝까지 유지되는 Context) - Activity가 종료되도 작동해야하는 작업의 경우 사용.
- applicationContext 로 접근
Activity Context.
- Activity 사이클을 따라가는 Context.
- Activity 종료 시 메모리에서 사라짐.
- toast, dialog, DB접근, SharedPreferences 같은 녀석들을 사용할 때 씀.
- Activity 내부에서 this로 접근
[ Context 와 메모리 누수 문제 ]
위 이야기를 통해 Context가 뭔지와 종류를 파악해봤다.
근데 위 컨텍스트를 잘못 쓴다면 메모리 누수가 발생하게 된다!!
메모리 누수 발생 원인
1. ViewModel에서 Activity Context를 참조할 경우 누수 발생
Why?
ViewModel 생명주기를 공부하면 알겠지만, ViewModel은 Activity보다 오래 살아있는 특징이 있다.
만약 Activity 사용도중 화면 돌림이 발생한다면,
Viewmodel은 그대로 유지되고, Activity는 Destroy 된 후 다시 create 되는 단계를 거치게된다.
ViewModel에서 Activity Context를 참조한다면 Activity가 Destroy 될 때 GC(Garbage Collecter)가 해당 Context를
메모리에서 지우지 못하는 일이 발생한다.
(그 Context 객체가 참도되고있으니!)
그렇게 사용도 안되는 녀석이 메모리에 남아 GC에 의해 안 치워친다면, 우린 이것을 메모리 누수라고 부른다.
이녀석이 쌓여 우리가 만든 앱이 느려지고 무거워지고 비효율적으로 된다..
반드시 유의해야한다..!!
그 밖에도 다음과 같은 상황에서 누수가 발생다고 한다.
- Non - static inner class로 선언된 Handler를 Activity에 사용할 경우..?
- View를 Static 변수로 선언하고 Activity가 이를 참조할 경우
- Singleton에서 Activity를 참조할 경우
제대로 된 활용 예시
- 만들려는 싱글톤 객체가 Context를 필요로 할 때, Application Context 사용
- Toast, Dialog등 Activity내부에 종속되어있는 요소에 Cotnext가 필요할 때, Activity Context 사용
그냥 다 Application Context를 다 써버리면 안되나?
- GUI (View Component 등) 관련 동작들은 Application에서는 오류 발생 확률 높음
- Activity는 Garbage Collection이 가능하지만, Application은 앱 프로세스가 살아있는 동안 계속 남아있음 ⇒ 할당 해제하지 않으면 끝까지 남아 메모리 누수 발생
- 따라서 가장 가깝고 밀접한 Context를 골라줘야 한다
이제 다음 포스팅에서는 ViewModel에서 Context를 쓸 수 있는 방법 위주로 다뤄보겠다!!
학부생 레벨에서 쓴 글로, 다소 부족한 부분이 있을 수 있으니 친절한 피드백을 매우 환영합니다.
'Android' 카테고리의 다른 글
| [Android] Companion Object 와 초기화 타이밍!! (2) | 2023.07.25 |
|---|---|
| [Android] JVM 과 Static 멤버의 특징 (메모리, 초기화 ..) (2) | 2023.07.13 |
| [Android] Fragment의 정의와 필요성, Lifecycle 및 이에 따른 대응. (0) | 2023.06.25 |
| [Android] Activity Lifecycle 과 화면회전 시 변화 (0) | 2023.06.22 |
| [Android] Activity 가 있는데 Fragment는 왜 써? (0) | 2023.06.05 |