iOS 메모리 관리툴 – Zombies

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

iOS SDK 를 설치하면 Instruments 라는 iOS Performance 분석 어플리케이션이 같이 설치된다. (Instruments User Guide)

이번 포스팅에서는 iOS 개발 학습 중에 본인이 직면했던 초보적(?)인 문제와 이를 Instruments 의 Zombies 를 이용하여 해결한 내용을 다룬다. (참고로 본인의 개발 환경 버전은 다음과 같다 –  iOS 4.3 , Xcode 3.2.6, Instruments 2.7 )

< Instruments 의 Zombie 선택 화면 >

Zombies 는 iOS 메모리 할당 내역 전반을 확인할 수 있는 툴로서 특히 over-released object (zombie object 라 칭함) 를 찾는데 도움을 준다.

Xcode 상에서도 아래 그림과 같이 Run 메뉴에서 Instruments 를 연동하여 메모리 할당 내역을 확인할 수는 있다. 그러나 Xcode 상에서는 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 -> Application 폴더 내에 있다.) 실행하면 아래 그림처럼 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 라는 의미다. 메시지 끝의 화살표를 클릭하면 zombie 객체(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 를 사용할 때 문제가 발생하였던 것이다. (이 코드가 정상적으로 돌아가는 경우도 있다.)

</pre>
MyAppDelegate *myAppDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

[self  setMyObject : [myAppDelegate myObject]];

[myAppDelegate release];

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

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


self.window.rootViewController = self.navigationController; // 이렇게 하면 rootViewController 에서 myAppDelegate release 하면 죽음

//[self.window addSubview:navigationController.view]; // 이렇게 하면 rootViewController 에서 myAppDelegate release 해도 안죽음

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

* 잘못된 내용이 있거나 위에서 기술한 본인 프로젝트의 문제 관련하여 가르침 주실 분들은 코멘트 부탁드립니다.

Advertisements
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: