Скользящее окно MappedByteBuffer

Существуют ли какие-либо способы заставить MappedByteBuffer иметь скользящее окно в файле. У меня очень большой файл (20 ГБ), но я хочу делать только 100 МБ за раз. Я пробовал это, просто отбрасывая старый буфер и создавая новый из канала, но это съедает память, поскольку старые буферы, похоже, не используются повторно.

Есть идеи?


person Mike Streeton    schedule 05.03.2012    source источник


Ответы (1)


Вы можете заставить старый буфер немедленно освободить память с помощью

((DirectBuffer) buffer).cleaner().clean();

Отказ от ответственности: я использовал это только с обновлением Sun/Oracle/OpenJDK Java 6 18 и более поздних версий. Он может быть недоступен или работать некорректно со старыми версиями или другими платформами. Спасибо @EJP.


Если у вас нет 32-битной ОС, я бы просто сопоставил весь файл в памяти (используя несколько сопоставлений). Это будет намного эффективнее и проще в управлении. В этой ситуации я очищаю ByteBuffers только как часть закрытия файла (в модульных тестах).

Вы можете использовать ТБ виртуальной памяти и использовать очень мало физического или даже дискового пространства. В этом примере я сопоставляю 8 ТБ виртуальной памяти с машиной с 24 ГБ памяти и диском на 120 ГБ.

http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html

Подводя итог: на 64-битной машине виртуальная память удивительно дешева, и вам не о чем беспокоиться.

Кстати: большинство 64-битных машин на самом деле ограничены 48-битной виртуальной памятью. Это предел в 256 ТБ, а не 16 ЭБ (18 000 000 ТБ), которые они могут адресовать теоретически.


Вы можете найти эту библиотеку интересной. Я не упоминал об этом ранее, так как это может вам не подойти, но вы можете найти интересными подход и некоторые приемы, которые я использую в коде.

https://github.com/peter-lawrey/Java-Chronicle

person Peter Lawrey    schedule 05.03.2012
comment
Вы должны указать, что DirectBuffer и другие классы, на которые здесь полагаются, являются sun.misc.* классами и, следовательно, подлежат обычным предостережениям. Я впервые увидел все это в связи с 1.4: неужели это все еще работает? - person user207421; 06.03.2012
comment
@EJP, как вы указали, это не будет работать на всех системах. Однако на Sun/Oracle и OpenJDK JVM, по крайней мере, это работает очень хорошо. Я использую этот подход в производстве около двух лет (и на двух разных работах). - person Peter Lawrey; 06.03.2012
comment
Самым ранним из них будет обновление 18 для Java 6, последнее обновление 3 для Java 7. Интересен вопрос, работает ли оно для всех версий с NIO (начиная с Java 1.4). - person Peter Lawrey; 06.03.2012