1. 힙 개념
- 1-1 스택과 힙의 차이
- 1-2 힙 메모리 사용
- 1-3 힙 메모리 할당과 해제
- 1-4 힙의 특징
2. 박싱과 언박싱- 2-1 박싱(Boxing)
- 2-2 언박싱(Unboxing)
- 2-3 박싱과 언박싱 피하는 방법
3. 재네릭의 개념
힙은 컴퓨터 메모리에서 동적 할당을 위해 사용되는 메모리 영역이다.
힙은 주로 프로그램 실행 중에 런타임에 객체나 데이터를 할당하고, 그 메모리를 자유롭게 관리할 수 있도록 제공한다.
힙은 스택(Stack)과 함께 중요한 메모리 관리 영역을 형성하며, 각 역할이 다르다.
스택(Stack)
- *고정 크기의 메모리 영역이다.
- 함수 호출 시 지역 변수와 함수의 매개변수 등이 저장된다.
- 변수의 생명 주기가 함수의 실행 흐름과 함께 결정되며, 자동으로 할당 및 해제된다.
- LIFO(Last In, First Out) 방식으로 동작한다.
- 속도가 빠르며, 메모리 관리가 간단하지만, 할당 크기와 사용 가능 범위에 제한이 있다.
힙(Heap)
- 동적 메모리 할당에 사용되는 영역이다.
- 메모리의 크기가 런타임에 결정되며, 필요할 때 언제든지 메모리를 할당하고 해제할 수 있다.
- 객체와 같은 참조 타입 데이터가 주로 저장된다.
- 가비지 컬렉션(Garbeage Collection)을 통해 불필요한 메모리가 자동으로 회수된다.
- 속도가 느리며 메모리 할당과 해제 과정에서 오버헤드가 발생할 수 있다.
힙은 주로 객체를 저장할 때 사용하고, C#에서는 참조 타입 객체들이 힙에 저장된다.
EX ) 클래스 인스턴스(new 연산자 사용)나 배열 같은 데이터는 힙 메모리 영역에 할당된다.
- 클래스 인스턴스와 배열 : 객체를 생성하면 그 객체의 데이터가 힙에 저장되고, 그 객체에 대한 참조는 스택에 저장된다.
할당 : 힙은 런타임에 동적으로 메모리를 할당한다. new 연산자나 특정 메서드를 호출하여 객체를 생성하면 메모리가 할당된다.
해제 : 힙에서 할당된 메모리는 자동으로 해제되지 않는다. C#에서는 가비지 컬렉션(GC)이 불필요한 객체를 자동으로 수거하여 메모리를 해제한다. 가비지 컬렉터는 객체가 더 이상 사용되지 않을 때, 즉 참조가 끊어졌을 때 해당 메모리를 회수한다.
동적 할당
메모리는 프로그램 실행 중에 동적으로 할당되고, 필요하지 않게 되면 해제한다.
new연산자나 메서드를 호출하여 객체를 생성할 때 마다 힙에 메모리가 할당된다.메모리 관리
힙 메모리는 가비지 컬렉션에 의해 관리된다.
가비지 컬렉터는 객체의 참조가 끊어졌을 때 해당 메모리를 회수하고, 불필요한 메모리를 자동으로 정리한다.성능 고려
힙 메모리 할당은 속도가 상대적으로 느리며, 메모리 할당과 해제 과정에서
추가적인 *오버헤드가 발생할 수 있다.
동적 할당이 가능하므로 유연성이 뛰어나며, 크기가 변하는 데이터나 객체를 처리할 때 유용하다.
박싱(Boxing)
박싱(Boxing)은 값 데이터(예:
int,char,double등)을 참조 타입(예:object)으로 변환하는 과정이다.
박싱을 통해 값 타입의 데이터를 힙(Heap)에 할당하고, 이를 참조 타입처럼 다룰 수 있게된다.
박싱의 특징
- 값 타입의 데이터를 참조 타입인
object로 변환- 힙에 객체로 할당되어 참조로 다룰 수 있게 됨
- 성능 오버헤드가 발생 : 박싱은 메모리 할당과 복사가 일어나므로 성능에 영향을 미칠 수 있다.
언박싱(Unboxing)
언박싱(Unboxing)은 참조 타입으로 박싱된 데이터를 다시 값 타입으로 변환하는 과정
언박싱의 특징
- 형 변환이 필요하며, 잘못된 형으로 언박싱을 시도하면
InvalidCastException이 발생할 수 있다.- 박싱된 객체에서 실제 값을 추출하는 과정이미로 성능 오버헤드가 발생할 수 있다.
재네릭(Generic)을 사용하면 박싱과 언박싱을 피할 수 있다. 재네릭은 값 타입과 참조 타입을 처리할 때 형 변환 없이 안전하게 다룰 수 있도록 해준다.
재네릭이란?
재네릭(Generic)은 프로그래밍에서 일반화(Generalization)을 적용한 기법으로, 타입을 동적으로 지정할 수 있도록 해주는 기능이다.
동일한 코드나 데이터 구조가 여러 데이터 타입에서 동작할 수 있도록 할 수 있다.
재네릭(Generic)은 C#에서 코드의 유연성, 재사용성, 그리고 타입 안전성을 높여주는 중요한 기능이다.일반화(Generalization)이란?
- 일반화는 특수한 개념에서 공통된 개념을 찾아 묶는 것이다.
- 다양한 데이터 타입을 다루는 메서드(함수)를 만들 때, 각각의 타입을 별도로 처리하지 않고, 하나의 일반적인 방식으로 처리할 수 있도록 만드는 것이다
C#에서 재네릭은 타입 파라미터(매개변수)를 사용하여 다양한 타입을 처리할 수 있도록 해주는 프로그래밍 기법이다.
클래스, 인터페이스, 메서드 등에 타입을 일반화하여, 코드의 재사용성을 높이고 타입 안전성을 제공하는데 사용한다.재네릭(Generic)의 장점
1. 타입 안전성 : 코드에서 사용하는 타입이 컴파일 타임에 결정되므로, 타입 오류를 줄일 수 있다.
2. 재사용성 : 다양한 타입을 처리하는 코드를 작성할 때, 같은 코드를 재사용하여 작성할 수 있다.
3. 성능 : 재네릭을 사용하면 박싱(Boxing)과 언박싱(Unboxing) 오버헤드를 피할 수 있어, 성능이 향상될 수 있다.
<T>와 같은 형태로 타입 파라미터를 명시한다.C#에서는 제너릭 타입에 대해 제약 조건(Constraints)을 설정할 수 있습니다. 이를 통해, 제너릭 타입이 특정 조건을 만족하는 타입만 받도록 제한할 수 있습니다.
형식 매개변수 : 재네릭 자료형을 나타낸다