Direct vs Indirect vs Memory Mapped (어떤 메모리를 버퍼로 이용할것인가에 따라)

Java NIO (New Input/Output) API는 효율적인 I/O 작업을 위해 ByteBuffer 클래스를 도입했습니다. ByteBuffer는 JDK 1.4에서 java.nio 패키지와 함께 소개되었으며, JVM 힙 내의 바이트 배열뿐만 아니라 JVM 외부의 메모리에서도 작동할 수 있습니다. Java에는 주로 세 가지 종류의 ByteBuffer가 있습니다:

  1. Direct ByteBuffer

  2. Indirect ByteBuffer

  3. MappedByteBuffer

1. Direct ByteBuffer (직접 버퍼)

  • 메모리 위치: Direct ByteBuffer는 JVM 힙 외부에 메모리를 할당합니다. 이 메모리는 운영 체제의 네이티브 메모리와 직접 상호작용합니다.

  • 생성 방법: ByteBuffer.allocateDirect(int capacity) 메서드를 사용하여 생성합니다.

  • 성능: 일반적으로 I/O 작업에서 더 나은 성능을 제공합니다. JVM 힙과 네이티브 I/O 계층 간의 추가 복사 단계를 피할 수 있기 때문입니다. 고성능 애플리케이션에 적합합니다.

  • 가비지 컬렉션: Direct ByteBuffer는 JVM 힙 외부에 있으므로 JVM 가비지 컬렉션의 영향을 받지 않습니다.

  • 사용 사례: 파일이나 네트워크 채널에서 데이터를 자주 읽고 쓸 때 이상적입니다.

2. Indirect ByteBuffer (비직접 버퍼)

  • 메모리 위치: Indirect ByteBuffer는 JVM 힙 내에 있는 바이트 배열을 감싸는 래퍼입니다.

  • 생성 방법: ByteBuffer.allocate(int capacity) 메서드를 사용하여 생성합니다.

  • 성능: JVM 힙 내에서 작동하므로 I/O 작업 중 추가 복사 오버헤드가 발생할 수 있습니다.

  • 가비지 컬렉션: JVM 힙의 일부이므로 JVM 가비지 컬렉터가 관리합니다.

  • 사용 사례: I/O 작업의 오버헤드가 중요하지 않거나, JVM 힙 외부 메모리에 직접 접근할 필요가 없는 경우에 적합합니다.

3. MappedByteBuffer (메모리 매핑 버퍼)

  • 메모리 위치: MappedByteBuffer는 파일의 메모리 매핑 영역을 나타내는 직접 버퍼의 일종입니다. JVM 힙 외부에 위치합니다.

  • 생성 방법: FileChannel.map(FileChannel.MapMode mode, long position, long size) 메서드를 사용하여 생성합니다.

  • 성능: 파일을 직접 메모리에 매핑하므로 파일 I/O 작업에서 매우 효율적입니다. 버퍼에 대한 변경 사항이 파일에 직접 반영됩니다.

  • 가비지 컬렉션: Direct ByteBuffer와 마찬가지로 JVM 가비지 컬렉션의 영향을 받지 않습니다.

  • 사용 사례: 대형 파일 또는 파일의 일부를 직접 메모리에서 조작해야 하는 애플리케이션에 이상적입니다.

파일 I/O 작업:

  • 네이티브 I/O 작업: 자바의 네이티브 API를 사용하여 운영 체제의 저수준 API를 직접 호출합니다. 이 방식은 성능이 더 우수하지만, 복잡성이 높을 수 있습니다.

  • 일반 I/O 작업: 자바의 고수준 API를 사용하여 데이터를 처리합니다. 이 방식은 구현이 간단하고 JVM 힙 메모리를 사용합니다.

주요 차이점 요약 표

구분

Direct ByteBuffer

Non-Direct ByteBuffer

MappedByteBuffer

메모리 할당

OS Native Memory

JVM 힙 내부

JVM 힙 외부, 파일을 직접 메모리에 매핑

가비지 컬렉션

영향 X

영향 O

영향 X

성능

I/O 작업에서 더 나은 성능 제공

추가 복사 오버헤드 발생 가능

대형 파일 조작에서 매우 효율적

실제 사용 사례

빈번하고 빠른 I/O 작업이 필요한 고성능 애플리케이션에 적합

일반적인 용도의 애플리케이션에 적합

대형 파일을 다루는 애플리케이션에 최적

Direct vs Indirect 성능 비교

실행 결과

Direct가 성능이 좋게 나오는 편이긴 하나 안좋을때도 보인다.

횟수
1GB 파일 복사하는데 걸린 시간

1차

Direct: 493 ms

Indirect: 716 ms

2차

Direct: 589 ms

Indirect: 510 ms

3차

Direct: 467 ms

Indirect: 778 ms

4차

Direct: 470 ms

Indirect: 621 ms

5차

Direct: 919 ms

Indirect: 855 ms

6차

Direct: 1011 ms

Indirect: 1535 ms

8차

Direct: 939 ms

Indirect: 1261 ms

코드

Last updated