C#에서 가비지 컬렉터가 메모리를 자동으로 처리하지만, 비관리 리소스나 개발자의 실수로 메모리 누수가 발생할 수 있다. 이를 방지하기 위한 문법이 있다.
파일 핸들이나 소켓의 경우 GC가 처리하지 않기 때문에 정리를 위하여 Dispose()를 호출하여 명시적으로 정리해준다.
또는 using 구문을 사용하여 리소스를 정리하면 된다고 한다.
이벤트 핸들러 또한 해제하지 않으면 메모리 누수가 발생할 수 있기 때문에 -=
로 해제해주어야 한다.
GC는 자동으로 메모리를 관리하지만 필요시, GC.Collect()
로 강제 수집이 가능하며 빈번한 호출은 성능 저하를 유발할 수 있기 때문에 주의가 필요하다.
비슷한 모습을 가진 구조체와 클래스가 어떠할 때 사용되는지 알아보았는데, 메모리 관리 방식과 사용 목적이 다르다고 한다.
잘못된 선택은 애플리케이션의 성능과 안정성에 영향을 미친다고 한다.
구조체는 값 형식으로 스택에 저장되며 값 복사를 통해 독립적인 데이터를 유지한다. 물론 스택 메모리가 가득 찼을경우 힙 영역 메모리를 사용하기도 한다고 한다. 이를 언제 사용하는가, 작고 단순한 데이터를 표시할 때 즉 좌표나 RGB 등을 표현할 때 사용되고 성능이 중요한 애플리케이션의 경우 GC가 자주 발동되지 않는게 중요하기 때문에 스택에 저장되어 GC에 영향을 덜 받는 구조체를 사용한다.
클래스는 참조형식으로 힙 영역에 저장된다. 객체에 대한 참조를 공유할 수 있고 가비지 컬렉터가 메모리 해제를 관리한다.
구조체는 대규모 데이터를 다루기에는 오버헤드로 인해 부적합하여 이럴 때 클래스를 사용하고 상속과 다형성이 필요할 때, 상태 변경을 해야할 때 사용한다고 한다. 다만 객체가 필요 이상으로 참조되면 메모리가 해제되지 않아 GC에 부담이 되는 상황이 발생한다.
특성 | 구조체 | 클래스 |
---|---|---|
메모리 위치 | 스택(Stack) | 힙(Heap) |
사용 용도 | 작고 간단한 불변 데이터 | 크고 복잡하며 상태가 변경 가능한 데이터 |
메모리 관리 | 가비지 컬렉션 영향 적음 | 가비지 컬렉션 관리 필요 |
복사 동작 | 값 복사 (깊은 복사) | 참조 복사 (얕은 복사) |
성능 | 박싱/언박싱 최소화 시 빠름 | 참조와 동적 할당으로 대규모 데이터에 유리 |
상속 | 지원하지 않음 | 지원함 |