수준별 학습 세션 - C# 메모리 특강

Amberjack·2024년 2월 1일
0

C# 문법

목록 보기
42/44

구조체와 클래스의 차이?

여러 차이가 있겠지만, 출제자의 의도를 파악해보자. 튜터님 왈, 이 경우 십중팔구는 메모리의 이해에 대해 묻는 것이라고 말씀하셨다.

구조체는 값 형식, 클래스는 참조 형식이다.

Heap, Stack 메모리

먼저, 메모리의 종류에 대해 알아보자.

메모리의 종류

  • Code : 프로그래머가 작성한 코드를 보관
  • Data : Static, const, 전역 변수 등 어플리케이션 전반에 필요한 데이터가 저장됨
  • Heap : 참조 데이터 저장 -> 객체
  • Stack : 로컬 변수, 매개 변수 저장 등 어플리케이션 실행 순서에 필요한 데이터 보관 -> 변수

Stack 메모리 할당

int x = 10; 를 선언한다고 생각해보자.

우리는 메모리의 주소 값을 x를 통해 불러올 수 있게 된다.

Stack 메모리의 경우 0번지에서부터 차곡차곡 쌓인다 -> Stack

Heap 메모리 할당

Heap의 경우는 메모리 고유의 알고리즘에 의해 구현되며, 거의 랜덤이라 봐도 무방하다.

Person chad = new Person(); 이 있다고 가정해보자.

객체의 경우, Heap에 실제 객체가 저장이 되고, Stack에는 객체의 변수(혹은 참조)에 Heap의 주소 값이 저장된다.
위의 chad의 경우, 실제 객체 new Person()이 힙에 저장이 되고, 변수 chad에는 new Person()의 힙 주소 값이 저장된다.

인스턴스(ex. new Person())가 힙에 저장되고 인스턴스의 참조(ex. chad)가 스택에 저장 된다.

때문에,

Person chad = new Person();
Person yeom = chad;

라는 코드가 있을 때, chad와 yeom은 서로 같은 힙 주소를 저장하게 된다. 때문에 chad의 값이 변경이 되면 yeom 또한 변경되게 된다.

메모리 해제

Stack

지역 변수는 변수가 선언된 스코프를 벗어나면 삭제된다.

Heap

Heap의 경우, 스코프가 벗어나도 사라지지는 않는다.
참조된 것이 없을 때 가비지 컬렉터에 의해 수거가 되는데, 이는 스코프와는 상관없다.

Heap은 new를 통해 생성되고, GC에 의해 수거된다.

Vector를 Update()에서 계속 new로 할당해도 괜찮은 이유?

구조체는 값 형이기 때문에 Vector의 경우 Update에서 new를 해도 괜찮다.

메모리 파편화

문자의 불변성

문자는 한번 할당되는 순간 변하지 않는다. 따라서 string 에 += 연산을 통해 다른 문자열을 추가하면 새로운 메모리에 새롭게 할당을 해서 string + string으로 저장한다. 결과적으로 기존에 있던 string과 새로 생긴 string + string이 생긴다. 이를 메모리 파편화라고 한다.

해결 방법

  1. string 을 한번에 제작. -> 보간 문자열, string.Format 등...

  2. StringBuilder의 사용
    StringBuilder를 통해 문자열을 계속 추가한 뒤, StringBuilder.ToString()을 통해 파편화를 피하고 문자열을 합쳐서 만들 수 있다.

StringBuilder의 동작 원리

stringBuilder는 메모리의 크기를 처음부터 크게 잡는 방식으로 해결한다.
이후 문자열을 추가하거나 제거한 뒤에 ToString()으로 문자열로 변환한다.

전역변수

static, const의 경우, Data 메모리에 저장된다.
어플리케이션 전반에 필요한 데이터들을 저장하기 때문에, 프로그램이 시작하자마자 메모리에 저장이 되고, 프로그램이 종료될 때 해제가 된다. 때문에, static이나 const의 경우, 따로 할당을 하지 않고 사용할 수 있다.

0개의 댓글