Отображение памяти огромных файлов в Java - PullRequest
8 голосов
/ 22 марта 2019

Возможно ли отображать в памяти огромные файлы (несколько ГБ) в Java?

Этот метод FileChannel выглядит многообещающе:

MappedByteBuffer map(FileChannel.MapMode mode, long position, long size)

И position, и size допускают 64-битные значения - пока что все хорошо.

Однако

MappedByteBuffer предоставляет методы только для 32-битных позиций (get(int index), position(int newPosition) и т. Д.), Что, по-видимому, означает, что я не могу отобразить файлы размером более 2 ГБ.

Как мне обойти это ограничение?

Ответы [ 2 ]

7 голосов
/ 22 марта 2019

Взгляните на Использование файла сопоставления памяти для огромного матричного кода , который показывает, как создать список MappedByteBuffer, каждый размером менее 2 ГБ, для сопоставления всего файла:

private static final int MAPPING_SIZE = 1 << 30;
...
long size = 8L * width * height;
for (long offset = 0; offset < size; offset += MAPPING_SIZE) {
    long size2 = Math.min(size - offset, MAPPING_SIZE);
    mappings.add(raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2));
}

Согласно JDK-6347833 (fs) Расширение MappedByteBuffer для поддержки размеров> 2 ГБ на 64-разрядных платформах причина ограничения 2 ГБ:

MappedByteBuffer - это ByteBuffer с дополнительными операциями для поддержки отображаемых в памяти файловых областей. Для поддержки отображения области, превышающей Integer.MAX_VALUE, потребуется параллельная иерархия классов. Пока единственное решение - создать несколько MappedByteBuffers, каждый из которых соответствует области размером не более 2 ГБ.

3 голосов
/ 22 марта 2019

Как уже упоминалось, MappedByteBuffer имеет ограничение в 2 ГБ из-за использования целочисленных указателей индекса / позиции.

Чтобы обойти это, вы можете использовать альтернативную реализацию, такую ​​как larray

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...