IT정보사전

[IOS] 메모리 관리툴 - Zombies 본문

모바일 프로그래밍

[IOS] 메모리 관리툴 - Zombies

작은나무0530 2018. 12. 7. 00:09
728x90
반응형

안녕하세요~ 작은나무입니다!!

iOS개발은 java, C#과 달리 메모리 관리를 개발자가 직접 해줘야 한다. 이에 메모리 할당은 어플리케이션 성능에 있어 중요한 부분을 차지하고 있다. 다행히 Apple은 어플리케이션의 메모리 관리를 할 수 있는 툴을 제공한다.

iOS SDK를 설치하면 Instruments라는 iOS Performance분석 어플리케이션이 같이 설치된다. (Instruments User Guide)
이번 포스팅에서는 iOS개발 학습 중에 본인이 직면했던 초보적(?)인 문제와 이를 Instruments의 Zombies를 이용하여 해결한 내용을 다룬다


Zombies는 iOS메모리 할당 내역 전반을 확이할 수 있는 툴로서 특히 over-released object (zombie object라 칭함) 를 찾는데 도움을 준다.
Xcode상에서도 아래 그림과 같이 Run메뉴에서 Instruments를 연동하여 메모리 할당 내역을 확인할 수는 있다.

그러나, Xocde상에서는 Zombies는 비활성화 되어 있고, Leaks, Allocations는 전반적인 메모리 할당 내역을 확인 할수는 있지만 Zombies에서와 같이 직접적인zombie object를 확인 할 수 없다. 다시 말해 over-released object로어플리케이션이 종료되어도 Leaks, Allocations로는 그 원인을 바로 확인하시 어렵다.



먼저 본인의 iOS 프로젝트에서 발생한 exception메시지를 확인해보자. 아래는 debug console 메시지다.


"unrecognized selector sent to instance라는 메시지 및 start 시점 부터의 진행 내용을 확인 할 수 있다.
-exception메시지 의미를 이번 포스팅에서 다루진 않겠다. 단, 해당 메시지 발생 원인 중 하나가 zombie object임을 알리고자 한다.

일반적으로 breakpoint생성 후 코드 한 라인씩 실행해가며 exception 발생부를 찾는 것이 디버깅의 방법이다.
그러나 본인의 프로젝트에서는 iOS Framework내부 토드가 실행되는 중에 exception이 발생하였던 터라 문제 원인을 찾기 위한 핵심 방법이 되지는 못했다.

문제 원인을 위 메시지만으로 파악하기 어렵다. zombies를 실행시켜보자. zombies를 가동하기 위해 Instruments를 실행시킨다. (Instruments는 iOS SDK 설치 경로 Developer ->Allication폴더 내에 있다.)
실행하면 아래 그림처럼 Template 선택 화면이 나오는대 iOS ->Simulator ->Memory ->Zombies를 선택한다.


Choose 클릭 후 보이는 화면에서 아래 그림과 같이 Choose Target을 선택하여 대상 프로젝트를 선택한다.
대상 프로젝트는 Zombies를 적용시키고자 하는 iOS 프로젝트로서 선택 경로는 프로젝트 폴더 ->build ->Debug-iphonesimulator ->실행파일 (아래 두번째 그림 참조)이다. 선택 후 Choose를 클릭하면 설정이 완료된다.
이제 좌측 상단의 빨간 점(Record)을 클힉하여 실행시키자.


실행결과 zombie object가 발견되면 친절히도 아래 그림과 같이 메시지가 나타난다.
zombie object가 발견되지 않으면 실행 중의 메모리 할당 내역을 실시간으로 모니터링 할 수 있다.
본인의 프로젝트 경우 4초만에 문제가 발생하였다. (이상한 점은 본인의 프로젝트의 경우 zombie object로 인한 어플리케이션 다운 현상이 간헐적으로 발생된다는 것이다. 그 이유는 아직 잘 모르겠다.
zombies로 문제 원인 확인하여 수정 후에는 동일 문제가 재발하지 않았다.)


zombies의 메시지는 Ox5b35390 주소의 object가 zombie라는 의미다. 메시지 끝의 화살표를 클릭하면 zomibe객체 (Ox5b35390 주소)의 reference count증감 이력을 확인 할 수 있다. (아래 그림 참조)
스크롤을 아래로 내려 마지막 행을 확인하면 zombie라는 단어를 확인 할 수 있고, 문제의 원인은 바로 위 단계인
-reference count를 0으로 만든 - 지점으로 유추 가능하다.


위 그림의 테이블에 나온 각 행들은 수행된 메소드를 의미한다. iOS Framework 내부 메소드가 아닌 개발자가 추가한 클래스의 메소드라면 여기서 바로 실제 코드 확인이 가능하다.
위의 경우, 좌측에 34로 명시된 행은 본인이 추가한 클래스의 정보를 나타내고 있다. 이 행의 Responsible Caller열 (최우측 열)을 클릭하면 reference count를 0으로 만든 코드를 바로 확인 할 수 있다. 이를 통해 zombie object 유발 코드를 쉽게 찾을 수 있고 적절히 수정하여 문제를 해결 할 수 있다.

본인의 문제를 간단하게 요약하면, 아래와 같이 Application Delegate객체를 다른 클래스의 초기화 메소드에서 사용 후 release를 시키는 코드가 있었는데, release하는 코드가 문제의 원인이었다.

release로 인해 Application Delegate가 메모리에서 해제 되었고 iOS Framework단에서 Application Delegate를 사용할 때 문제가 발생하였던 것이다. (이 코드가 정상적으로 돌아가는 경우도 있다.)

위 코드는 본인이 학습에 참고 하고 있는 개발서적의 코드와 동일하다. 학습 서적 프로젝트를 다운로드하여 실행하면 아무런 문제가 발생하지 않았지만, 본인의 프로젝트는 문제를 발생시켜 여러 디버깅 방법을 체험 할 수 있는 좋은 삽질 기회(?)를 제공하였다.

myAppDelegate를 alloc등으로 생성한 것이 아니여서 release를 하면 안될 것 같다라는 판단이 들지만 일단 학습 서적을 그대로 따라하였고, 학습서적 프로젝트와 본인 프로젝트의 실행결과의 차이는 고생 끝에 다른 곳에서 찾을 수 있었다.
그 차이는 Application Delegate실행부의 아래 코드와 같다. (Navigation 프로젝트를 선택하면 자동으로 포함되는 코드)

아직 저 두라인의 코드가 Framework단 내부에서 어떤 차이를 유발하는지 모르겠다. 하지만 메모리 관리 측면에서 문제가 되었던 release코드는 - 비록 학습서적에는 있더라도 -적절치 못한 것으로 판단한다.

728x90
반응형
그리드형
Comments