[객체지향] 6.고급 C# 메모리 관리와 최적화, 구조체와 클래스의 메모리 관리 차이

C#은 객체 지향 프로그래밍 언어로, 메모리 관리는 성능과 애플리케이션 안정성에 막대한 영향을 미칩니다. 메모리 관리에는
가비지 수집, 구조체와 클래스의 차이, 그리고 최적화 기법이 포함됩니다. 이 글에서는 C#의 메모리 관리와 최적화 방법,
구조체와 클래스의 메모리 관리 차이에 대해 깊이 있는 작성과 사례를 통해 설명하겠습니다.

1. C#의 메모리 관리 기본 개념

C#의 메모리 관리는 크게 스택(Stack)힙(Heap)으로 나뉩니다.
스택은 메서드 호출 시 생성되는 지역 변수들이 저장되는 메모리 공간이며, 메모리 할당과 해제가
즉시 이루어집니다. 반면, 힙은 동적으로 할당된 객체들이 저장되는 공간으로, 가비지 수집기(GC)에
의해 관리됩니다. 이러한 메모리 구조는 성능에 영향을 미칠 수 있습니다.

1.1. 스택(Stack)과 힙(Heap)의 특징

  • 스택: 지역 변수 저장, 빠른 임시 저장소, 메모리 해제가 신속함.
  • 힙: 동적 객체 저장, 메모리 해제까지 시간이 소요됨, GC의 영향을 받음.

2. 구조체와 클래스

C#에서 구조체와 클래스는 모두 사용자 정의 데이터형을 생성하는 방법입니다. 그러나 이 둘은
메모리 할당 방식과 사용 용도에서 차이가 있습니다. 구조체는 값 형식(value type)이고,
클래스는 참조 형식(reference type)입니다.

2.1. 구조체의 특성

  • 값 형식(value type): 스택에 저장됩니다.
  • 데이터를 직접 복사합니다.
  • 디폴트 생성자가 없습니다.
  • 상속을 지원하지 않습니다.

2.2. 클래스의 특성

  • 참조 형식(reference type): 힙에 저장됩니다.
  • 참조를 통해 접근합니다.
  • 디폴트 생성자를 제공합니다.
  • 상속을 지원합니다.

2.3. 구조체와 클래스의 메모리 관리 차이 예제

C#
public struct MyStruct
{
    public int x, y;
}

public class MyClass
{
    public int x, y;
}

위의 예제에서 MyStruct는 구조체로서 스택에 할당되며, MyClass는 힙에
할당됩니다. 이를 통해 메모리 할당 방식 차이를 이해할 수 있습니다.

3. 가비지 수집(Garbage Collection)

C#에서 가비지 수집은 사용되지 않는 메모리를 자동으로 해제하여 메모리 누수를 방지합니다.
그러나 가비지 수집기는 비즈니스 로직에 따라 여러 문제를 일으킬 수 있습니다. 따라서
성능 최적화를 위해 가비지 수집을 이해하고 최소화하는 것이 중요합니다.

3.1. 가비지 수집의 동작 원리

  • 메모리 사용 여부를 추적합니다.
  • 사용되지 않는 객체를 식별하여 해제합니다.
  • 세대(generation) 기법을 사용하여 성능을 최적화합니다.

3.2. 가비지 수집 최적화 기법

  • 객체의 수명을 줄이기 위해, 적절한 스코프에서 객체를 생성합니다.
  • 구조체를 사용하는 것이 더 적합한 경우에는 구조체를 사용합니다.
  • 객체 풀링(Object Pooling) 패턴을 활용하여 자주 생성되는 객체를 재사용합니다.

4. 성능 최적화 방법

메모리 관리 및 성능 최적화를 위해 적절한 기법을 적용해야 합니다. 여기에 몇 가지
최적화 기법을 소개합니다.

4.1. 불필요한 객체 생성 줄이기

C#
// 나쁜 예
public void Add(int number)
{
    List<int> values = new List<int>();
    values.Add(number);
}

// 좋은 예
public void Add(ref List<int> values, int number)
{
    if (values == null)
    {
        values = new List<int>();
    }
    values.Add(number);
}

4.2. 구조체 대신 클래스를 사용

많은 필드를 갖는 구조체는 스택 공간을 과도하게 사용하여 스택 오버플로우를 유발할 수 있습니다.
이러한 경우, 클래스를 사용하는 것이 더 안전할 수 있습니다.

4.3. 짧은 수명의 객체를 피하기

짧은 수명을 가진 객체는 가비지 수집을 증가시켜 성능 저하를 초래합니다. 객체를
재사용하거나 구조체를 활용하여 성능을 개선할 수 있습니다.

5. 결론

C#에서 메모리 관리와 최적화는 애플리케이션의 성능과 안정성에 매우 중요합니다.
구조체와 클래스의 차이를 이해하고 적절한 메모리 관리 기법을 적용하면
최적화된 코드를 작성할 수 있습니다. 성능 최적화를 위해 메모리 사용 패턴을 분석하고
가비지 수집 최적화 기법을 사용하는 것이 필요합니다.