투케이2K

205. (TWOK/WORK) [업무 이슈] 안드로이드 static 변수 선언 한 휘발성 데이터 유실로 데이터 null 전송 이슈 본문

투케이2K 업무정리

205. (TWOK/WORK) [업무 이슈] 안드로이드 static 변수 선언 한 휘발성 데이터 유실로 데이터 null 전송 이슈

투케이2K 2026. 3. 19. 19:40
728x90
반응형

[제 목]

주제 : 투케이2K 업무 정리

타이틀 : 투케이 / 2k / 업무 정리

제목 : [업무 이슈] 안드로이드 static 변수 선언 한 휘발성 데이터 유실로 데이터 null 전송 이슈

 

[내 용]

------------------------------------------------------------------------------
[개발 및 테스트 환경]
------------------------------------------------------------------------------

- 제 목 : [업무 이슈] 안드로이드 static 변수 선언 한 휘발성 데이터 유실로 데이터 null 전송 이슈


- 테스트 환경 : Android / Java


- 사전) 👉 static 변수 간략 설명 : 

  >> static 변수는 클래스에 소속된 변수로, 인스턴스(객체)에 소속되지 않습니다.

  >> static 변수는 클래스가 처음으로 로드되고 초기화될 때 단 한 번 만들어지며, 프로그램 전체에서 공유됩니다.

  >> static 변수의 생성과 초기화 타이밍 (JVM 클래스 로딩 수명주기) 은 클래스를 다룰 때 크게 로딩(Loading) → 링크(Linking: 검증/준비/해결) → 초기화(Initialization) 단계를 거칩니다

  >> static 변수가 null 이 되는 시점 : 

    - 코드에서 직접 null을 대입할 때

    - 클래스가 “언로드(unload)” 될 때 (클래스 로더가 회수될 때)
      $ static 필드는 클래스에 귀속되므로, 그 클래스를 로드한 클래스 로더가 더 이상 참조되지 않아 GC에 의해 회수되면, 그 클래스와 그 안의 static 필드도 함께 사라집니다.
    
    - (재)로딩 시 초기화가 다시 수행될 때
      $ 어떤 프레임워크가 클래스를 새로운 클래스 로더로 재로딩하면, 그 클래스는 새로운 “정적 영역” 을 다시 갖게 되고, 해당 static 필드들은 다시 준비 단계에서 기본값(null) 로 시작한 뒤 초기화 단계에서 재설정됩니다.

    - JVM 종료 시
      $ 프로세스가 내려가면 운영체제가 메모리를 회수합니다.

------------------------------------------------------------------------------





------------------------------------------------------------------------------
[이슈 사항]
------------------------------------------------------------------------------

1. 사용자가 앱을 장기간 백그라운드로 내린 상태에서 task 목록에 있는 앱 기능 동작 다시 수행 시 static 으로 선언한 변수가 null 로 전송 되는 이슈


2. 안드로이드 앱 프로세스가 정리되면서 static 변수 값도 모두 초기화 되어 선언 된 static 변수 값이 null 로 전송 되는 이슈


3. ✔️ (중요) 안드로이드 앱 프로세스가 종료 되었지만 task 목록 및 포그라운드 전환 시 이전 화면이 남아 있는 이유

  >> 안드로이드는 앱을 백그라운드로 보낼 때 해당 Activity의 스크린샷을 찍어 저장합니다.
  
  >> 앱 프로세스가 죽어도 , Activity 인스턴스가 없어져도 , View나 Data가 모두 사라져도 Recents 화면에는 마지막 스크린샷이 남아 있기 때문에 마치 앱이 살아있는 것처럼 보입니다.

  >> task 에 있는 앱 포그라운드 재진입 시도 시 이전 화면이 표시되는 것처럼 보이는 이유 정리 : 

    - 앱이 죽은 상태에서 Recents에서 다시 진입하면 OS는 이렇게 행동합니다
      $ 앱 프로세스 재시작
      $ Launcher Activity(앱 첫 화면)을 호출하는 대신
      $ Recents에 남아 있던 Task stack 정보를 기반으로
      $ 그 Task의 맨 위 Activity를 recreate() 해서 다시 만듭니다 (멤버 변수 · static 변수 등은 초기화됨(프로세스 새로 시작했으니까))

------------------------------------------------------------------------------





------------------------------------------------------------------------------
[원인 파악 및 증상 재현]
------------------------------------------------------------------------------

1. 특정 앱을 실행 한 후 기능 동작 > 장기간 백그라운드로 앱을 내립니다.


2. 특정 앱을 백그라운드로 내린 상태에서, 다른 앱 사용 및 동영상 시청 등 다른 활동 수행 실시


3. ✔️ (중요) Android OS 에서 자동으로 백그라운드 프로세스 kill 이 된 것 확인

  >> 포그라운드 앱이 메모리가 필요할 때

  >> 장시간 백그라운드 + 시스템 메모리 압박

  >> 오래된 앱 우선 정리 정책(LRU 프로세스 리스트)

  >> 사용자가 다른 앱을 많이 켬

  >> Android 시스템 정책(OOM ADJ)에 따라 필요 시 Kill


4. task 목록에 있는 앱을 다시 실행해서 기능 동작 수행 시 static 으로 초기화 되었던 변수가 null 로 초기화 된 것 확인

  >> 앱 프로세스가 죽으면 다음 실행 시 static 은 전체 초기화

------------------------------------------------------------------------------






------------------------------------------------------------------------------
[조치 내용]
------------------------------------------------------------------------------

✅ 방어 로직 [1] : 

  >> 앱 라이프 사이클 onPause 중지 상태 전환 시 타임 스탬프 저장 및 포그라운드 onResume 실행 시 타임 스탬프 값을 저장해 비교 수행

  >> 일정 시간 장기간 활동 없이 포그라운드로 전환 된 경우 경고 팝업 알림창 표시 수행 및 앱 정상 재실행 요청


✅ 방어 로직 [2] : 

  >> onCreate 에서 생성 된 static 변수들을 프리퍼런스 저장 공간에 재저장을 수행

  >> 앱 라이프 사이클 onResume 에서 static 변수 값 null 체크 후 초기화 된 경우 프리퍼런스에 저장된 값을 사용해 다시 재저장 수행

------------------------------------------------------------------------------





------------------------------------------------------------------------------
[참고 사이트]
------------------------------------------------------------------------------

[자바 : 싱글톤 (Singleton) 생성 및 사용하기]

https://kkh0977.tistory.com/366

https://blog.naver.com/kkh0977/222237455303?trackingCode=blog_bloghome_searchlist


[Java] 변수 값 초기화 이슈 - java.lang.NullPointerException : variable must not be null

https://kkh0977.tistory.com/5821

https://blog.naver.com/kkh0977/223403617663?trackingCode=blog_bloghome_searchlist


[S_Preference - 프리퍼런스 관리 클래스]

https://kkh0977.tistory.com/1622

https://blog.naver.com/kkh0977/222677830724?trackingCode=blog_bloghome_searchlist

------------------------------------------------------------------------------
 
728x90
반응형
Comments