Rust 할당자(Allocator) 트레이트(trait) 안정화, 무엇이 문제인가?

by DD
2개월 전
조회수 12

Rust의 할당자(Allocator) 트레이트(trait)는 아직 안정화되지 않았으며, 2025년 설문조사에서 많은 사용자가 안정화를 원한다고 응답함.

제로 사이즈 할당(Zero Sized Allocations), 컨텍스트(Context) 제공, 트레이트 분할(Splitting the Traits) 등 여러 쟁점이 안정화를 가로막고 있음.

Rust for Linux 팀은 안정화 없이 할당자를 사용하고 있으며, 컨텍스트(Context) 제공의 중요성을 강조함.

모노모르피즘(Monomorphization) 비용과 동적 디스패치(Dynamic Dispatch)의 장단점을 비교하며, C++ 및 Zig의 사례를 분석함.

제로 사이즈 할당(Zero Sized Allocations) 문제와 해결 방안

글에 따르면, 현재 할당자 트레이트는 제로 사이즈 레이아웃(Layout)을 허용하여, 제로 사이즈 타입(Zero Sized Types)에 대한 문제를 야기한다. 할당자 계약(Allocator Contract)은 동일한 포인터를 반환할 수 있으며, 이는 언디파인드 비헤이비어(Undefined Behaviour)로 이어질 수 있다. 해결책으로, NonZeroLayout 타입을 도입하여 할당 크기를 강제하는 방안이 제시되었지만, 트레이트 사용자에게 복잡성을 더할 수 있다는 단점이 있다.

Rust for Linux의 할당자 트레이트(trait) 설계

본문에서는 Rust for Linux 팀이 안정화되지 않은 할당자를 사용하며, 커널 환경에 특화된 설계를 채택했다고 언급한다. 특히, FlagsNumaNode를 도입하여 할당 요청에 대한 컨텍스트(Context)를 제공하는 점이 주목할 만하다. 이는 wg #138에서 논의된 내용으로, 할당자 트레이트에 컨텍스트를 포함하는 것이 중요하다고 강조한다. 이러한 접근 방식은 다양한 메모리 할당 시나리오를 지원하는 데 기여할 수 있다.

트레이트 분할(Splitting the Traits)을 통한 유연성 확보

글에서는 할당자 트레이트의 유연성을 높이기 위해 트레이트를 DeallocatorAllocator로 분할하는 방안을 제시한다. 특히, Bump Allocator와 같이 개별 해제가 필요 없는 경우, Deallocator를 활용하여 코드 크기를 줄일 수 있다. 하지만, 트레이트 분할이 트레이트의 단순성을 해칠 수 있다는 반론도 존재하며, 다양한 사용 사례를 고려하여 결정해야 한다.

연관된 에러 타입(Associated Error Type) 도입의 필요성

할당 실패 시, 더 많은 정보를 제공하기 위해 연관된 에러 타입(Associated Error Type)을 도입하는 방안이 제안된다. 현재는 AllocError라는 ZST(Zero Sized Type)를 반환하여, 실패 원인에 대한 구체적인 정보를 제공하지 못한다. 연관된 에러 타입을 사용하면, 할당 실패 시 구체적인 에러 정보(Detailed Error Information)를 반환하여, 호출자가 문제를 해결하는 데 도움을 줄 수 있다. 하지만, dyn 호환성(dyn Compatibility) 문제도 고려해야 한다.

모노모르피즘(Monomorphization) 비용과 동적 디스패치(Dynamic Dispatch)

글에서는 할당자를 사용할 때 발생하는 모노모르피즘(Monomorphization) 비용과 동적 디스패치의 장단점을 비교 분석한다. 특히, 컨테이너에 새로운 제네릭 인자가 추가되어 코드 변경이 많아지는 문제를 지적하며, C++ 및 Zig의 사례를 통해 동적 디스패치의 가능성을 제시한다. Zig는 동적 디스패치를 사용하여 코드 비대화를 줄이고, LLVM을 통해 정적 호출로 변환하는 최적화를 수행한다. Rust에서도 dyn Allocator를 사용하여 동적 디스패치를 구현할 수 있다.

The State of Allocators in 2026