블로그 이미지
따뜻한 코드 만들기 리본매냐

카테고리

분류 전체보기 (34)
.NET (6)
Database (5)
Daily life (11)
세미나 후기 (0)
마음의 지식 (7)
코드 (1)
Python (1)
외출 (3)
Total41,216
Today7
Yesterday22

달력

« » 2019.6
            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            

공지사항

태그목록

http://dalbong2.net/trackback/72 에서 퍼옴

메모리 관리를 설명하는 부분을 보면 항상 나오는 말들인데도, 처음 개발에 들어선 개발자들에겐 돌아서면 헛갈리는 부분이다. 이 포스트에서는 이것들의 차이점을 정리해 본다. 

■ null !

이것의 의미는 분명하다. 메모리상에 존재하는 객체에 대한 모든 참조의 끈을 끊는다는 의미이다. 만약 메모리상의 객체를 참조하는 변수가 모두 null로 되면 메모리상의 객체는 가비지 컬렉트 (Garbage Collect)후보가 된다. 이때 가비지 컬렉팅이 일어나면 해제된다.

null의 원래 의미는 이렇지만, .NET 프레임워크에서는 디버깅모드와 릴리스 모드( + 최적화모드)에 따라서 다르게 해석할 수 있다. 다음 코드를 보자.

[STAThread]

static void Main()

{

    Timer t = new Timer();



    // 필요한 작업을 한다.


    Console.Read();


    t = null;

}

필요한 작업을 하고 코드는 사용자로부터 키 입력을 기다릴것이다. Main 메소드가 호출될때 이 메소드는 컴파일(JIT 컴파일)되고 Timer 객체 t가 메모리에 생성될 것이다. 그러나 Timer 객체를 참조하는 t에 null을 설정함으로써 이제 이 객체를 가리키는 참조가 하나도 없게 된다. 만약 최적화 옵션(그런 것이 있단다-_-;;)이 활성화된 상태의 JIT 컴파일러가 컴파일을 하게 되면 이 경우 Timer객체를 참조하는 변수가 하나도 없다고 판단한다.

그래서 사용자로부터 키 입력을 기다리고 있는 동안 가비지 컬렉팅이 수행되면  이 Timer 객체는 가비지 컬렉션의 후보가 될 것이다.  메소드가 아직 실행중이라는 것은 객체의 가비지 컬렉팅을 막아주지 못한다는 사실을 염두에 둘 필요가 있다.

그러나 디버깅 모드에서는 메소드(여기서는 Main)도 하나의 가상 참조(참조 그래프상의 "Root"노드가 되는 것이다)로 여긴다. 무슨 말인가 하면 Main 메소드라는 참조가 Timer 객체를 참조하고 있다고 해석하는 것이다. 결과적으로 디버깅모드에서는 가비지 컬렉팅이 일어나도 Timer객체는 살아남게 되는 것이다.

그러나 어플리케이션이 디버깅 모드에서는 잘 돌아가다가 릴리스 모드에서는 에러가 발생한다면 난처한 일이 아닐 수 없다. 이것을 해결하는 방법으로 객체를 해제할때 null대신에 Dispose 메소드를 사용하면 된다.

■ Finalize 메소드

.NET에서 Finalize 메소드는 일반 메소드와 달리 클래스명 앞에 틸드(~)가 붙어서 "~클래스명() "형태를 갖는 메소드를 말한다. 어떤 타입에 대해서 Finalize 메소드를 정의해놓게 되면 가비지 컬렉팅 작업에 의해서 객체가 수거되려고 할때 GC는 그 타입의 Finalize 메소드를 호출해서 정의된 메모리 해제 작업을 수행한다.

■ Dispose 메소드

Finalize 메소드는 GC가 호출하는 메소드인 반면에 Dispose 메소드는 객체의 클라이언트가 직접 호출할 수 있는 메소드이다. null은 객체의 메모리 해제 시기를 결정할 수 없다. GC(Garbage Collector)가 컬렉팅을 수행할때까지 메모리에 남게 된다. 해서 객체를 사용하는 클라이언트측에서 직접 객체가 차지하는 자원을 해제할 수 있는 방법을 제공해줄 수 있는 방법이 Dispose 메소드이다. 앞의 코드를 Dispose()를 이용해서 변경하면 다음과 같다.

[STAThread]

static void Main()

{

    Timer t = new Timer();



    // 필요한 작업을 한다.


    Console.Read();

    t.Dispose(); // t = null;

}

이런 식으로 코딩을 하면 디버깅 모드이든, 최적화된 릴리스 모드이간에 Timer 객체에 대한 참조가 여전히 유효하게 되어 Timer 객체는 가비지 대상이 되지 않는다.  (-> Dangling Reference??)

■ Dispose 패턴

IDisposable 인터페이스를 구현하는 .NET 프레임워크 제공의 모든 객체들은 Dispose() 메소드를 호출해서 클라이언트가 직접 원하는 시기에 해제할 수 있도록 하고 있다. 만약 Dispose()를 지원하는 타입을 사용자가 직접 정의한다면 Dispose()에서 자원을 해제하는 코드를 원하는 대로 넣으면 된다.

Dispose()를 직접 정의할때 주의할 점은 클라이언트가 직접 Dispose()를 호출해서 자원을 해제했다면 그 자원 해제 사실을 GC가 알 수 있도록 표시를 해 줘야 한다. 그래야  이미 해제 했던 자원을 GC가 또 해제하지 않을 수 있게 된다. 만약 또 해제하려고 한다면 에러가 발생한다. 따라서 Dispose 패턴 이라는 것이 나오게 된다. 이 패턴은 객체의 클라이언트와 GC가 자원 해제를 중복되게 시도하지 않고 안전하게 자원을 해제할 수 있는 코딩 패턴을 말해준다. 실제 Dispose 코딩 패턴에 대해서는 "dipose pattern"이라는 검색어로 구글링해보면 자세히 알아 볼 수 있을 것이다.

Posted by 리본매냐

Alice in Wonderland!!

Daily life / 2009.07.09 00:27
이상한 나라의 앨리스
어릴적 동화책으로.. 만화로..
그리고 카셋테이프로...  읽고 보고 들었던 이야기
초딩땐 잠들기전까지 항상 세계명작만화 테이프를 틀어놓고잤다.
앨리스가 하얀토끼를 따라 이상한 나라로 모험을 떠난다.
모자장수와 산쥐 그리고 3월의 토끼의 티타임이 시작될 무렵이면
이미 꿈나라에서 앨리스와 뛰어다니곤했다.

어른(? 30이면 어린이나 청소년은 아니지..)이 되어 다시 읽은 주석달린 앨리스..
주석에 너무 연연하지 않고 자연스럽게 읽어나갔다.
슬픈건 어린시절 이야기만 들어도 머리속에 상상되던 장면들이
삽화를 통해서야 머리속에 그려진다는거 ㅠㅠ

현실적이지 않으면 이해가 어려운 어른이 되기 싫었던 난 어느새 그런 어른이 되어버린거다.
작가인 루이스캐럴은 "예쁜" 여자 아이를 무척이나 좋아했고
이 글 역시 캐럴이 일하던 대학의 학장의 딸 앨리스 리델를 위해 쓴 이야기다.
앨리스에게 청혼까지 하려했다니 심히 로리타증후군이 의심되지만...
그에 대한 어떤 글(내가 찾은한에서다..)에서도 그가 변태적이라는 설명은 없다.
그는 어린 여자 아이의 순수함을 사랑했고 고귀하게 생각했다고 한다.

이야기의 결말은 앨리스의 모험은 결국 꿈이었다는거...
어찌보면 허무하긴하다.
예전에 파리의 연인도 모든 것이 여주인공의 꿈이라는 결론으로 끝나 시청자들의 비난(?)를 받기도 했듯이 ...
그러나 앨리스의 꿈은 계속된다..
앨리스의 꿈에서가 아니라 언니의 상상속에서..

더보기




Posted by 리본매냐

시나브로

Daily life / 2009.07.08 23:54

드를 수정하면서, 조금씩 깔끔하게 만들라.
설계 개선을 멀리까지 앞서 나가게 하고 싶은 유혹에 저항하라.

오늘 여러분에게 영향을 미치는 설계만 개선하는 습관을 길러라.
오랜 시간에 걸쳐 건드려야 할, 더 큰 개선들의 목록을 만들고 공개하라.

설계는 기술 쪽 사람과 비즈니스 쪽 사람 사이에 신뢰 관계를 맺는 일에 봉사해야 한다.

최초 구현을 시작할 수 있을 정도로만 설계하라
경험을 바탕으로 설계할 수  있을 때까지 그리고 결정 내용을 즉각 사용할 수 있을 때까지 설계를 미룬다.

"언제나 설계하라"

결과

소프트웨어를 더 빨리 배치할 수 있다.
확신을 가지고 결정을 내릴 수 있다.
잘못된 결정을 계속 끌어안고 사는 일을 피할 수 있다.
처음 설계 할 때 내린 가정들이 다른 것으로 대체되더라도 개발 속도를 유지할 수 있다.

일자리는 낮은 임금을 찾아 이동하지 않는다.
일자리는 성실성과 책임감을 찾아 이동한다.

카이젠(Kaizen) 지속적으로 조금씩 자주 개량하는 것(일본어)


중요한 건 차곡차곡 쌓이는 것..
기술도.. 사랑도 시나브로

Posted by 리본매냐

최근에 달린 댓글

최근에 받은 트랙백

글 보관함