본문 바로가기
게임 개발 일지/내일배움캠프 TIL

[C#] 구조체와 클래스 / GC

by 빛하_ 2024. 1. 22.
기술면접 대비하기 #2

 

 

4.struct와 class를 비교해서 설명해주세요.

Struct와 Class 모두 데이터, 메서드, 프로퍼티 등으로 객체를 정의하는 데 사용한다. Class 는 객체 지향적 프로그래밍을 위해 코드의 다양성, 캡슐화를 지원한다. Struct는 데이터를 그룹화하기 위해 사용한다. 이 때, 구조체는 클래스와 다르게 상속이 불가능하다.

구조적 측면에서의 차이로는, Struct(구조체)는 값 타입이기 때문에 스택에 할당된다. 따라서 구조체가 크면 스택 할당량이 커지므로 주로 간단한 데이터를 작은 규모로 구현할 때 사용한다. Class(클래스)는 참조 타입이기 때문에 힙에 동적으로 할당된다. 따라서 데이터 규모를 확장할 때 용이하다. 또한 클래스의 데이터 (매개변수)는 참조한 다른 객체들에서 수정이 가능하다. 구조체의 기본 접근 제한자는 public이고 클래스는 private이다. 

Struct는 사용이 끝나면 파기되지만, Class는 참조가 끝나도 남아있기 때문에 가비지 컬렉터를 사용하게 된다.

 

 

5.가비지 컬렉터에 대해 설명해주세요.

C++은 개발자가 직접 힙 메모리에 할당된 객체를 해제해야 하지만, C#은 CLR이라는 .NET 가상머신 환경에서 구동되므로 GC 기능을 제공해 힙 메모리를 관리할 수 있다. GC는 힙 메모리의 사용량이 일정 수준을 넘어가거나, 메모리가 부족한 경우 호출된다. 또는 사용자가 Collect 메서드를 이용해 직접 호출할 수도 있다. GC가 호출되면 어디에서도 참조되지 않는 힙 메모리를 찾아 해제한다. 이 때, 사용하지 않지만 참조가 유지되는 메모리는 해제하지 않는다. 

GC의 장점은 개발자가 메모리 관리를 직접 하지 않아도 누수를 해결해준다는 것이다. 하지만 호출 시 오버헤드가 발생하여 성능 하락이 발생할 수 있고 호출 시점을 개발자가 정하기 어렵다는 단점이 있다. 

 

* CLR : Common Language Runtime (공용 언어 런타임)

.NET 에서 지원하는 가상머신으로, 운영체제가 아닌 가상머신에서 구동되는 C#은 다양한 플랫폼에 최적화가 가능하다.

 

시스템에서 사용하지 않는 메모리를 찾아 자동으로 청소해주는 역할을 한다. 힙 영역의 메모리를 주기적으로 검사해 참조되고 있지 않은 객체를 모아서 청소한다. 하지만 이런 시스템 역시 자동으로 실행되기 때문에 프로그램 성능에 영향을 줄 수 있는 부분이다. 특히 힙 메모리를 얼만큼 사용하는지에 따라 가비지 컬렉터의 비용이 증가할 수 있다. 

그리고 힙에 할당된 인스턴스의 메모리는 해제할 수 있지만, 해당 인스턴스의 외부 리소스까지는 해제하지 못한다.

따라서 가비지 컬렉터가 효율적으로 작동할 수 있도록 개발자는 최적화 전략에 더욱 신경써야 한다.

 

6.가비지 컬렉터를 회피하기 위한 전략은 무엇이 있나요?

1) 객체 재사용

객체를 재사용하면 객체의 반복 생성과 파괴를 줄일 수 있다. 오브젝트 풀링이 이런 목적으로 사용된다. 

2) 불필요한 메모리 할당 피하기

반복문 내에서 새로운 객체를 생성하는 대신 객체를 미리 생성하고 필요에 따라 값을 변경하는 방법을 사용한다. 

3) 값 타입 사용

값 타입은 스택에 저장되므로 가비지 컬렉션의 대상이 되지 않는다.

4) 대용량 객체 사용 최소화

대용량 객체 힙에 할당된 개체는 GC 과정에서 부담을 가중시킨다. 

5) Finalizer 사용 최소화

파이널라이저를 가진 객체는 GC 과정에서 부담을 가중시킨다.

6) IDisposable 패턴 구현 

필요한 경우 IDisposable 인터페이스를 통해 관리되지 않는 자원을 직접 해제한다. 

 

가비지 컬렉터 회피 전략의 핵심은 힙 메모리를 사용하는 '참조 타입 인스턴스'사용을 줄이는 것이다.

참조 타입의 대안으로 값 타입 사용이 대표적이다. 값 타입 인스턴스는 기본적으로 스택 메모리 영역을 사용하므로 가비지 컬렉터에 닿지 않는다. 하지만 크기가 커지거나 배열 형태일 경우 힙 메모리를 사용하므로 주의해야 한다.

오브젝트 풀링 사용도 하나의 전략이다. 객체를 해제하지 않고 시스템 내에서 재사용하는 방법이다. 객체의 생성과 해제를 줄임으로써 가비지 컬렉터 동작을 감소시킬 수 있다. 

 

 

 

 

 

댓글