Bytebuffers 및 NIO를 사용할 때 OutOfMemoryError를 피하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/28675

문제

ByteBuffersFileChannels를 사용하여 바이너리 데이터를 파일에 씁니다.큰 파일에 대해 또는 여러 파일에 대해 연속적으로 수행하면 OutOfMemoryError 예외가 발생합니다. 나는 다른 곳에서 NIO와 함께 Bytebuffers를 사용하는 것이 깨져서 피해야한다고 읽었습니다.이미 이런 종류의 문제에 직면하여 Java의 파일에 많은 양의 바이너리 데이터를 효율적으로 저장하는 솔루션을 찾았습니까?

jvm 옵션 -XX:MaxDirectMemorySize를 사용하면 좋을까요?

도움이 되었습니까?

해결책

한 번에 모든 데이터를 포함하는 거대한 ByteBuffer를 만들지 않는다고 말하고 싶습니다.훨씬 더 작은 ByteBuffer를 만들고 데이터로 채운 다음이 데이터를 FileChannel에 씁니다.그런 다음 ByteBuffer를 재설정하고 모든 데이터가 기록 될 때까지 계속합니다.

다른 팁

Java의 Mapped '직접 버퍼'라고도하는 바이트 버퍼 . 기본적으로이 메커니즘은 OS의 가상 메모리 페이징 시스템을 사용하여 버퍼를 디스크에 직접 '매핑'합니다. OS는 디스크와 메모리 사이의 바이트 이동을 매우 신속하게 자동으로 관리하므로 가상 머신 옵션 변경에 대해 걱정할 필요가 없습니다. 이를 통해 이상한 해킹없이 기존 Java 스트림 기반 I / O에 비해 NIO의 향상된 성능을 활용할 수 있습니다.

내가 생각할 수있는 유일한 두 가지 문제점은 다음과 같습니다.

  1. 32 비트 시스템에서는 매핑 된 모든 바이트 버퍼의 총계 가 4GB 미만으로 제한됩니다. (실제로 애플리케이션의 한계이며 이제 64 비트 아키텍처에서 실행됩니다.)
  2. 구현은 JVM에 따라 다르며 요구 사항이 아닙니다. 썬의 JVM을 사용하는데 문제는 없지만 YMMV입니다.

    Kirk Pepperdine (다소 유명한 Java 성능 전문가)은 웹 사이트 www.JavaPerformanceTuning.com에 참여하고 있으며 여기에는 MBB 세부 정보가 더 있습니다. NIO 성능 팁

무작위 방식 으로 파일에 액세스하는 경우 (여기에서 읽고, 건너 뛰고, 쓰고, 뒤로 이동) 문제가있는 것입니다;-)

하지만 큰 파일 만 작성한다면 스트림 사용을 진지하게 고려해야합니다.java.io.FileOutputStream는 float, int, Strings 또는 직렬화 가능한 객체 작성의 편의를 위해 바이트 단위로 직접 파일을 작성하거나 다른 스트림 (예 : DataOutputStream, ObjectOutputStream)에 래핑 할 수 있습니다.파일 읽기를위한 유사한 클래스가 있습니다.

스트림은 임의로 작은 메모리 (거의)에있는 임의의 대용량 파일 을 편리하게 조작 할 수 있도록합니다.대부분의 경우 파일 시스템에 액세스하는 데 선호되는 방법입니다.

transferFrom 메소드가 도움이 될 것입니다. 이전 답변에서도 지적했듯이 한 번에 모두가 아니라 채널에 점진적으로 작성한다고 가정합니다.

특정 JDK 공급 업체 및 버전에 따라 달라질 수 있습니다.

일부 Sun JVM의 GC에 버그가 있습니다.직접 메모리 부족은 기본 힙에서 GC를 트리거하지 않지만 직접 메모리는 기본 힙의 가비지 직접 ByteBuffer에 의해 고정됩니다.주 힙이 대부분 비어 있으면 오랫동안 수집되지 않습니다.

JVM이 사용자를 대신하여 직접 버퍼를 생성 할 수 있기 때문에 직접 버퍼를 사용하지 않는 경우에도 화상을 입힐 수 있습니다.예를 들어, 직접적이지 않은 ByteBuffer를 SocketChannel에 작성하면 실제 I / O 작업에 사용할 수있는 직접 버퍼가 생성됩니다.

해결 방법은 적은 수의 직접 버퍼를 직접 사용하고 재사용을 위해 보관하는 것입니다.

앞의 두 답변은 상당히 합리적으로 보입니다.명령 줄 스위치가 작동할지 여부는 메모리 사용량이 제한에 도달하는 속도에 따라 다릅니다.사용 가능한 메모리를 3 배 이상 늘릴 수있는 충분한 램과 가상 메모리가없는 경우 제공된 대체 제안 중 하나를 사용해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top