[펌] Object-C 메모리 관리 연구

오브젝트씨를 처음 접하면서 가장 난해하고 이해하기 힘든 부분중 하나가 메모리 관리 부분입니다.

C의 경우 메모리 관리는 alloc과 free로 이뤄집니다.
a = malloc(size);
....
free(a);
와 같은 형태이죠.
C++도 마찬가지입니다. 생성자와 소멸자를 호출해서 메모리 관리를 하게 됩니다.
Class();
....
~Class();
물론 malloc, free도 사용합니다.
자바의 경우는 조금 다른데, 가비지 콜렉터라는 것이 있어서 따로 메모리 관리를 해줄 필요가 없습니다.
a = new A();
이렇게 생성해서 쓰기만하면 가비지 콜렉터가 감시를 하다가 쓸모없어지면 메모리에서 삭제를 합니다.
물론 급하게 메모리를 늘려야 하는 상황이거나 메모리걱정을 조금 덜고 싶다면 다 사용한 객체에 대해서는
a = null;
과 같이 해두면 다음번 가비지 콜렉터가 수행될때 바로 메모리에서 삭제됩니다.

오브젝트씨의 경우는 new, alloc, retain과 release의 쌍으로 이루어집니다. 얼핏보면 C/C++과 같은 형태로 보입니다만 autorelease와 retain이라는 개념때문에 약간 다릅니다. 오브젝트씨에서는 레퍼런스카운트라는걸 사용합니다. new, alloc, retain과 같은 경우엔 카운트가 1증가하고 release시엔 1감소하지요. 카운트가 0이 될때 비로소 메모리에서 삭제됩니다.
(주의, OSX에서는 가비지 콜렉터를 지원하기에 메모리 관리 걱정이 조금 덜하다고 합니다. 하지만 iPhone개발시에 카비지 콜렉터가 없고, 애플에서는 autorelease도 권장하고 있지 않습니다.)
a = [A alloc];
...
[a release];
이것이 기본 형태입니다.
a = [A alloc];//1
...
[a retain];//2
...
[a release];//1
...
[a release];//0
이것이 retain을 썼을 경우입니다.
객체를 지역내에서만 사용할 경우엔 아무 문제가 없습니다만 객체를 다른 메세지에 던지거나 다른 객체에서 참조를 하게 될 경우에 문제가 생깁니다.
a = [A alloc];
[b message:a];
[a release];
이런 경우가 됩니다. 이때 b의 message가 단순히 한번 실행되고 마는 경우라면 문제가 없지만 addSubView라던가 addSubView라던가... 객체를 지속적으로 참조하는 경우라면 이야기가 달라집니다. 메세지를 던지고 난 후에 a객체를 release해버리면 카운트가 0이 되어서 메모리에서 삭제됩니다. 그러면 그 이후에 b객체는 a객체에 참조를 어떻게 할까요?
b는 a객체를 retain해주고 b가 dealloc될때 a를 release해줍니다. 따라서 위의 코드만 보기에는 a가 릴리즈된 이후에 b가 a를 참조하지 못할것처럼 보이지만 실제로 레퍼런스 카운트가 2로 증가했다가 1이 되므로 메모리상에 남아있게 됩니다. b가 객체의 사용을 끝낸후에 release하면 그때 카운트가 0이 되어서 메모리에서 삭제됩니다.

오브젝트씨에서는 다음과 같은 코딩 방법을 추천합니다.
모든 다른 객체를 참조 할 경우에는 항상 retain해서 카운트를 1 증가시키고 사용이 끝난후에 release해서 카운트를 1 감소시킵니다. new, alloc, retain이 아닌 경우엔 autorelease에 등록되므로 release하지 않아도 됩니다. 객체를 새로 만들때에도 이 룰을 지켜야 나중에 헷갈리지 않습니다.
autorelease에 대한 내용을 위에 안썼는데 main.m에 보시면 이렇게 되어있습니다.

NSAutoreleasePool *pool = [NSAutoreleasePool new];

int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");

[pool release];

a = [[[A alloc] init] autorelease];

이렇게 하면 a객체는 오토릴리즈 풀에 등록되고 풀이 릴리즈될때 같이 릴리즈됩니다.

[NSString stringWith어쩌고] 형태의 메세지들이 오토릴리즈를 사용한다고 생각하면 됩니다.

[NSData dataWith어쩌고] 이런 형태들 말이죠.

다시 한번 말하지만 아이폰 개발시에는 오토릴리즈를 사용하지 않는것이 좋습니다.


덧글

댓글 입력 영역