Collection Object Dispose() 쉽게 하기...... :: iopeni - Think of C#

객체 소거에 대한 단상....


얼마 전 아는 분이 몇가지 기술 적 자문을 구해 오셔서 그분 회사의 코드를 보던 중 질문 하신 범위 밖의 코드가 아주 심각한 문제가 있음을 발견 했습니다. 보고도 이야기 하지 않았습니다만..... 이야기 한다고 해서 그분이 이해 하시기엔 상당한 에로 사항이 있을꺼라는 ..... 제가 나쁜 놈이겠죠?


엔더스 헤일스버그라는 이 시대의 용자 께서는 .Net 을 설계 하시며, 절대 어플리케이션이 죽어서는 안된다 라는 명제를 가지고 정말 많은 고민을 하시었고(정말 고민을 했는지는 저도 모릅니다. 그냥 추측일 뿐입니다.)  생성된 객체가 소거 되었을 때, 누군가 소거된 객체를 호출 할 경우 어플리케이션의 종료를 막을 수 없고, 이 문제를 해결 하기 위하여, 가베지 컬렉터를 사용하여, 1세대, 2세대등...  사용자가 소거를 하여도 즉시 소거 되지 않고 가베지 컬렉터가 정말 사용하지 않는 객체를 소거 할 수 있도록 하는 시스템을 설계 하셨습니다.


아시는 분의 회사 코드를 보면 다음과 같은 황당한 코드가 담겨 있습니다.


private LIst<object> = new List<Object>();


public void funcion()

{

list.Clear();

list.ADD(new userControl);


//Todo....

}


그리고 화면에서 function을 호출 합니다.


결국 메소드가 한번 호출 될 때 마다 List를 비우고 다시 객체를 생성하여, 리스트에 담아 두게 되는데, 담겨 있는 객체를 소거 하는 문장은 어디에서도 찾아 볼 수 없습니다.결국 만든 유저 컨트롤 또 만들고, 또 만들고, 또 만들고........


엔더스 헤일스버그라는 이 시대의 용자가 설계한 마인드로 볼 때 결국 위와 같은 코드로 생성된  UserControl은 프로그램이 종료 될 때 까지 절대 소거 되지 않습니다. 


즉 Memory Leak 이 발생 한 거죠. 


만약 이 유저 컨트롤이 정말 큰 데이타를 취급 하게 된다면.... 이 프로그램이 메모리 부족 오류를 던지며, "나 일 못하겠다... 써글..." 이라고 이야기 하는 것은 시간 문제 입니다.


하나의 프로세스당 제한된 스레드 갯수... 하나의 스레드당 제한된 메모리 량을 생각 해 보면..... 사용 컴퓨터의 용량에 따라 어느 정도 가변적 이겠으나, 아주 위험한 코드죠 위와 같은 코드는.....


그래서 컬렉션에 있는 객체를 어떻게 소거 하여야 할까? 라는 문제를 생각해 보면 상당히 많은 방법들이 존재 합니다.


아주 무식한 방법으로 컬렉션에 담겨 있는 Controls를 Foreach로 순환 하며, 명시적 타입 캐스팅을 통한 타입 캐스팅 이후 각 타입이 가지고 있는 Dispose()를 호출 할 수도 있으나, 만약 저 List에 담기는 타입이 늘어 나면 늘어 날 수록 이 방법은 절대적 부담으로 작용 합니다. 


리스트에 담겨 있는 타입을 타입 캐스팅 해서 그 타입이 소거 대상 타입이라면 소거 하라는 메소드로 이관 하고 그 이관된 각 객체가 정말 이 시점에서 소거 하여야 하는 가를 검증 하는 잡이 발생 하게 되면... 이건 정말... 가관 입니다.


욕 나오는 코드를 작성 하게 되죠... 아마도 많은 초급 개발자 분들 께서는 이렇게 난해한 코드를 작성 하리라 생각 합니다.


그래서 살짝 힌트 아닌 힌트를 정리 합니다.


컬렉션에는 아주 유용한 메소드가 하나 있습니다.


ofType 메소드가 바로 그것이죠... 


이거에 확장 메소르를 하나 연결 하면 아주 쉬운 정리가 이루어 집니다. 다음 처럼 말이죠


//확장 메소드.

public static void ForEach<TItem>(this IEnumerable<TItem> sequence, Action<TItem> action)

        {

            // ToDo... 유효한 제거 인지에 해당하는 검증 작업 수행

                  검증하자....

// ---------------------------------------


            foreach(var item in sequence)

            {

                action(item);

            }

        }


// 컨트롤 클래스에서의 사용 이후 리스트 삭제 시점..

collection.OfType<IDisposable>().ForEach(ex => ex.Dispose());

collection.Clear();



짧은 코드로 원하는 잡을 수행 할 수 있다는 ..... ^^ 유용한 코드 입니다.





'Functional World > C#' 카테고리의 다른 글

라운드 트립 서식...  (0) 2015.05.06
널 병합 연산자.....  (0) 2014.12.15
윈도우 8.1 에서의 장치 독립적 코드 작성을 위한 DPI 설정 방법  (0) 2014.06.22
Form.ActiveForm  (0) 2013.11.07
바이트 배열 취득  (0) 2013.10.01
Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,