.NET 프레임워크에서는 성능과 리소스 효율성을 위해 다양한 풀링(Pooling) 기법이 사용된다. 풀링은 공통적으로 "객체를 필요할 때마다 새로 생성하지 않고, 재사용 가능한 객체를 미리 만들어두거나 다시 활용하는 방식"이다. 이 글에서는 ASP.NET을 포함해 .NET 환경에서 자주 사용되는 주요 풀링 기법을 정리한다.
1. HttpApplication Pooling
개념
ASP.NET은 웹 요청이 들어올 때마다 HttpApplication 인스턴스를 새로 생성하지 않고, 일정 수의 인스턴스를 미리 생성해 풀(pool)에 보관하고 요청 처리 시 재사용한다.
목적
- 요청마다 객체를 생성하는 비용을 줄임
- GC(가비지 컬렉션) 부담 완화
- 스레드 연결 및 이벤트 핸들링 최적화
관련 클래스
- HttpApplicationFactory
- HttpApplication (요청 수명주기 이벤트 포함)
2. Thread Pooling
개념
.NET의 ThreadPool은 작업(예: 비동기 처리, 타이머, 병렬 처리 등)을 수행할 때 매번 스레드를 생성하지 않고, 미리 생성된 워커 스레드 풀에서 스레드를 할당하여 실행한다.
목적
- 스레드 생성/종료 오버헤드를 줄임
- 효율적인 CPU 사용
- 대규모 요청 동시성 처리 가능
사용 방식
- ThreadPool.QueueUserWorkItem(...)
- Task.Run(...) 또는 async/await는 내부적으로 ThreadPool을 활용
관련 클래스
- System.Threading.ThreadPool
- System.Threading.Tasks.Task
3. Connection Pooling (DB 연결 풀)
개념
데이터베이스에 접속할 때마다 새 연결을 만드는 대신, 동일한 연결 문자열을 사용하는 연결을 풀에서 재사용한다.
목적
- DB 연결 생성/해제 비용 감소
- 트랜잭션 처리 성능 향상
- 대량 접속 시 서버 부하 감소
사용 방식
- 대부분의 ADO.NET Provider에서 자동 지원
- 커넥션 문자열과 풀 설정
- Server=myServer;Database=myDb;User Id=...;Password=...;Max Pool Size=100;
관련 클래스
- System.Data.SqlClient.SqlConnection
- System.Data.Common.DbConnection
4. Object Pooling (사용자 정의 객체 풀)
개념
개발자가 직접 생성 비용이 비싼 객체를 재사용하기 위해 풀을 구성하는 방식이다.
예: 문자열 버퍼, XML 파서, 커스텀 컨트롤러 등
목적
- GC 부담 완화
- 반복 사용되는 비싼 리소스의 재사용
- 고성능 실시간 시스템에 유리
구현 방식
- 직접 Queue<T>, Stack<T>, ConcurrentBag<T> 등을 이용해 객체를 관리
- .NET Core 이후로는 Microsoft.Extensions.ObjectPool 패키지 지원
예시
var pool = new DefaultObjectPool<MyExpensiveObject>(new DefaultPooledObjectPolicy<MyExpensiveObject>());
var obj = pool.Get();
// 사용 후
pool.Return(obj);
5. Socket/Buffer Pooling (네트워크 기반)
개념
SocketAsyncEventArgs 등 네트워크 I/O 객체와 버퍼(byte[])를 풀로 관리하여 고성능 네트워크 서버를 구현한다.
목적
- 비동기 I/O 성능 향상
- GC 빈도 최소화
- 네트워크 서버에서 병목 제거
관련 기술
- SocketAsyncEventArgs
- ArrayPool<T> (System.Buffers)
풀링이 필요한 이유
풀링은 단순히 "재사용" 그 이상의 가치를 제공한다. 고성능 시스템에서 다음과 같은 장점이 있다.
- 리소스 생성 비용 절감: 스레드, DB 커넥션, 객체 등 생성 비용이 큰 자원을 절약
- GC 부담 완화: 객체를 자주 생성하지 않아 메모리 파편화 방지
- 성능 일관성 확보: 병목 구간 없이 안정적인 처리 가능
- 확장성 확보: 동시 요청 수가 늘어나도 부드러운 확장 가능
마무리
풀링은 .NET 프레임워크의 보이지 않는 곳에서 핵심 역할을 수행한다.
특히 웹 애플리케이션이나 고성능 서버 개발 시에는 이러한 내부 동작을 이해하고 적절히 활용할 줄 아는 것이 중요하다.
실제 프로젝트에서 풀링 관련 성능 병목이 발생하거나 조정이 필요할 경우, 해당 풀의 설정값(Max Pool Size, Min Threads 등)을 직접 조정하거나, 사용자 정의 풀 구현을 고려해보는 것이 좋다.
'Skills > ASP.NET' 카테고리의 다른 글
Visual Studio에서 IIS 원격 서버로 Web Deploy 배포하는 방법 (0) | 2025.07.16 |
---|---|
ASP.NET Web Forms 요청부터 응답까지, 내부 구조 완전 정복 (1) | 2025.06.22 |
.NET의 컴파일 과정: C#에서 IL, DLL, JIT, 기계어까지, 그리고 CLR의 역할 (0) | 2024.09.07 |
aspx와 ascx의 차이 (1) | 2024.09.07 |
bin과 obj 폴더의 역할 (0) | 2024.09.07 |