Struct는 값 타입(Value Type)의 사용자 정의 데이터 구조
값 타입을 참조 타입(object)으로 변환하는 과정
int num = 123; // Stack에 저장
object obj = num; // Boxing: Heap에 새로운 객체 생성하고 값 복사
참조 타입을 값 타입으로 다시 변환하는 과정
object obj = 123; // Boxing된 상태
int num = (int)obj; // Unboxing: Heap에서 값을 읽어 Stack으로 복사
1. 불필요한 Heap 할당
2. 성능 저하
// 나쁜 예: 반복문에서 Boxing
ArrayList list = new ArrayList();
for(int i = 0; i < 10000; i++)
{
list.Add(i); // 10000번의 Boxing 발생!
}
// 좋은 예: 제네릭 사용
List<int> list = new List<int>();
for(int i = 0; i < 10000; i++)
{
list.Add(i); // Boxing 없음
}
3. 추가 CPU 사이클
4. GC 압박
제네릭은 타입 안정성과 메모리 효율성을 동시에 확보하기 위해 도입됨. 특히 값 타입 작업 시 Boxing/Unboxing을 제거해서 성능과 메모리 관리를 크게 개선함.
대부분의 상황에서 정답: 커넥션 풀링, 쓰레드 풀링, 오브젝트 풀링 등
→ 즉 메모리 관점에서도 new를 반복해서 사용하기보단 가능하다면 캐싱해서 사용하는 게 낫다.
예전에 형변환 귀찮을때 +"";를 참 애용했었는데...ㅎㅎ
이제야 StringUtil의 존재 이유를 알았다...ㅎㅎ