일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- 제플린
- #ContentProvider #App DataShare
- 사용법
- #리사이클러뷰 어댑터
- 빗버킷 #bitbucket #authorization failed #깃
- retrofi
- #안드로이드
- retrofit
- 안드로이드해상도
- #SMS API #안드로이드 SMS #SMS Retriever
- 안드로이드 아키텍쳐
- 레트로핏
- #android #안드로이드 #glide #gif #이미지다운로드
- 메모리릭
- #안드로이드 개발자 #안드로이드 신입 #개발자 이직 #안드로이드 면접 #신입 개발자
- MVVM
- retrofit2
- zeplin
- 키스토어
- 안드로이드 익명클래스
- 안드로이드 메모리릭
- #리사이클러뷰
- 클린아키텍쳐
- 구글맵안돼요
- 안드로이드
- 리사이클러뷰 체크박스
- Today
- Total
땀이 삐질삐질 나는 개발 일기
[안드로이드] 익명클래스가 메모리릭을 유발하는 EU(이유) 본문
혹시 글을 읽고 계신 독자님도 이렇게 생각하고 계셨나요? 그렇다면... 오른손을 듭니다.... 그러고 얼굴과 가깝게 손을 듭니다.그대로 자신의 뺨을 때립.... 농담이구요^^ ...
이렇게 알고 계신다면 정말 잘못 알고계시는 부분 입니다.익명클래스가 메모리릭을 유발한다고 하는 것은 다름아닌 외부 클래스에 대한 참조를 끊지 못하기 때문입니다.명시적으로 해제하고 못하고 그런 이유가 아니에요 . 자바에서의 메모리 릭이란 일단 메모리가 할당되고 회수되는 절차부터 간단하게나마 설명드리고 지나가겠습니다.자바에는 어떤 인스턴스가 할당되면, heap이라는 메모리 영역에 선언된 인스턴스를 정의하게 됩니다.이 heap이라는 메모리 영역에 많은 객체들이 정의 되겠죠? 때로는 heap영역의 객체들 끼리도 서로를 참조하게 됩니다.이때 우리가 잘 작성한 코드라면, 안드로이드 기준으로, heap영역의 메모리가 부족할 때 GC가 호출되어 쓰지 않는 인스턴스들의 메모리 할당을해제하게 됩니다. 이때 해제하는 기준은 해당 인스턴스가 누군가에 의해 참조가 되고있냐? 없냐? 로 판단해 없다면 해제하게 됩니다.아직 누가 참조하고 있는데 해제를 해버린다면 예기치 못한 에러가 발생할 수 있겠죠? 정상적인 로직은 이렇습니다 만, 우리가 조심해야할 것은 메모리 릭인거죠. 메모리 릭이란 위의 설명처럼
안드로이드에서는 달빅 머신쪽에서 여차 저차한 로직에 의해 일정량의 가용 메모리를 할당받게 됩니다. 즉 유한하다는 말이죠.이런 상황에서 , 더이상 쓰지 않는 메모리지만, 해제되며 메모리가 확보되지 못 하고 남아있다면 정작 새로 어떤 로직이 수행될 때 메모리가 필요한데더이상 가용 메모리도 없고, 해제 할 메모리도 없다면 내가 기대한 작업이 보장되지 않겠죠??그렇기 떄문에 메모리 릭을 발생하지 않도록 코드를 작성하는 것이 굉장히 중요합니다.다시 익명클래스로 돌아와서 코드와 함께 살펴보겠습니다.
위와같이 정의를 해 두었을때 TestInner 클래스는 릭에 대해 안전합니다. 하지만 TestLeakClass는 안전하지 못 합니다.이유는 TestInner 클래스는 Outer클래스 즉 TestClass에 대한 참조가 없기 때문이고, TestLeakClass는 TestLeakClass를 생성 할 때 생성자에 넘겨준"new Runnable()" 이 녀석 때문입니다.익명 클래스는 필히 구현부를 만들어야하고, 그 구현부는 또 필히 Outer 클래스 내부에 속하게 됩니다. 고로 new Runnable ->익명클래스 인스턴스는
Outer클래스인 TestClass와 참조관계가 형성되어 버리죠 .
만약 외부에서 TestClass test = new TestClass(); , test.testMethod(); 이렇게 호출을 했다면 test인스턴스가 할일을 마치고 해제되어야 하는 타이밍에 new Runnable이 아직 종료가 안된 상황이라면 new Runnable이 Outer에 참조를 가지고 있기 때문에 해제 할수 없는 상황이 발생하게 됩니다. 그렇게되면 이것이 바로 메모리릭으로 이어지지요.이때 new Runnable이 종료가 안된 상황이라는 것은 가령 이런 상황입니다.
이런 상황이기에 오로지 익명으로 선언했기 때문에 , 명시적으로 프로그래머가 해제할 수 없다. 이런 이유에서의 메모리릭이 아니라참조관계가 형성이 되고, 해당 참조가 아직 지워질 수 없는 상황이 만들어졌다. 그렇기 때문에 메모리릭을 유발한다 라고 보는 것이 맞습니다.
'개발 Tip' 카테고리의 다른 글
[안드로이드] 심심해서 찍어본 Retrofit 동기 / 비동기 Feat.Rx (0) | 2020.04.22 |
---|---|
[안드로이드] 기본적인 Recyclerview ViewType으로 홀더 나누기, 다른 Layout만들기 (0) | 2020.04.16 |
[안드로이드] Recyclerview 제대로 알고 쓰자 ! (7) | 2020.03.10 |
[안드로이드] 키스토어 각종 해시값 쉽게 보는 방법 (0) | 2020.02.12 |
[안드로이드] Debug, Release, Google Signing ...Keystore? 뭐하는 녀석이지? (0) | 2020.02.12 |