스택 (Stack)
스택은 프로그램의 실행 흐름에 따라 자동으로 관리되는 메모리 영역입니다. 주로 함수 호출과 관련된 지역 변수와 매개변수가 이 영역에 저장됩니다.
특징:
- 자동 메모리 관리: 함수가 호출될 때 스택 프레임이 생성되고, 함수가 종료될 때 해당 프레임은 자동으로 제거됩니다. 이 과정에서 해당 프레임에 할당된 모든 변수도 자동으로 사라집니다.
- 속도: 스택은 메모리의 할당과 해제가 매우 빠릅니다. 이는 스택이 LIFO(후입선출) 방식으로 운영되기 때문입니다.
- 용도: 주로 각 함수의 실행에 필요한 지역 변수(값 타입)를 저장하는 데 사용됩니다. 또한, 참조 타입의 참조(주소)들도 스택에 저장되기는 하지만, 실제 객체는 힙에 위치합니다.
힙 (Heap)
힙은 동적 메모리 할당을 위한 메모리 영역으로, 주로 생명주기가 긴 데이터 또는 프로그램 실행 도중 크기가 결정되는 데이터(예: 객체)가 저장됩니다.
특징:
- 수동 메모리 관리: .NET 환경에서 힙 메모리의 할당과 해제는 가비지 컬렉터(GC)에 의해 자동으로 처리되지만, 개발자가 객체를 생성하고 사용하는 시점은 직접 관리해야 합니다.
- 가비지 컬렉션: 사용되지 않는 객체를 자동으로 찾아 메모리를 해제하는 메커니즘이 있습니다. 이는 메모리 누수를 방지하고, 프로그램의 안정성을 높여줍니다.
- 용도: 참조 타입의 객체(예: 클래스의 인스턴스, 배열 등)가 이 영역에 저장됩니다.
스택과 힙의 상호작용
C#에서는 값 타입과 참조 타입의 구분이 중요한데, 이는 스택과 힙의 사용 방식과 직접적으로 관련이 있습니다:
- 값 타입(int, struct 등)은 데이터가 스택에 직접 저장되며, 값을 복사할 때는 해당 값의 전체 복사본이 생성됩니다.
- 참조 타입(class, array 등)의 경우, 변수에는 힙에 저장된 데이터의 참조(주소)만 스택에 저장되며, 여러 변수가 동일한 힙 메모리 주소를 참조할 수 있습니다.
성능 고려사항
- 스택: 빠르고 효율적이지만 공간이 제한적입니다.
- 힙: 유연성이 높고 크기 제한이 적지만, 관리 비용이 더 크고 가비지 컬렉션으로 인한 성능 저하가 발생할 수 있습니다.