안드로이드 Activity 혹은, View들을 Static변수에 담는건 피하는게 좋다.

 

Java Life Cycle과 Android의 Component Life Cycle이 조금 차이가있기에 설명해보고자한다.

 

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 StaticRefLeakActivity extends AppCompatActivity {
 
    static Activity leakActivity;
    static TextView leakText;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_static_ref_leak);
 
        leakActivity = this;
        leakText = new TextView(this);
    }
 
}
 
 

 

위와 같은 코드가 있을때 메모리 참고는 아래그림처럼 된다.

static변수들은 process가 시작할때 초기화되고 static영역에 자리잡게된다. 클래스의 인스턴스와는 전혀 다른

메모리공간에 상주한다고 봐도된다.

 

그런데 위의 코드에서 Activity가 종료된다고 생각해보자.(다른화면으로의 전환) Activitiy가 종료된다는것은 안드로이드 컴포넌트의 수명주기가 종료되었다는것이다. 하지만 객체의 수명은 이제 GC에의해 참조되는것이 없으면 끝나게된다. 

 

하지만...static영역은 프로세스(앱의실행)가 끝나지 않았기에 아직 StaticRefLeakActivtiy를 참조하고있고 또한, 익명의 TextView 인스턴스 역시 참조당하고 있다. TextView인스턴스 역시 this(StaticRefLeakActivtiy의 인스턴스)를 참조하고있기에 문제가되는상황이다. (GC가 수거를못해감)

 

그렇기에 static에 뷰 혹은 액티비티 인스턴스를 담는것은 매우 위험하다. 

만약 정말 그래야하는 상황? 이 생긴다면 해제를 정말 기가막히게 잘해줘야할 것이다.

 

 

 

참고

 

https://medium.com/@zhangqichuan/memory-leak-in-android-4a6a7e8d7780

 

Memory leak in Android

If Java is your first programming language, most likely you will take memory management for granted and let the built-in JVM Garbage…

medium.com

 

+ Recent posts