Я последовательно обрабатываю большой файл, и я хотел бы сохранить большую его часть в памяти, 16 ГБ оперативной памяти, доступной в 64-битной системе.
Быстрый и грязный способ сделать это, просто обернуть входной поток в буферизованный входной поток, к сожалению, это дает мне только 2 ГБ буфера. Я бы хотел, чтобы это было в памяти побольше, какие у меня есть альтернативы?




Как насчет того, чтобы позволить ОС заниматься буферизацией файла? Вы проверили, как влияет на производительность отказ от копирования всего файла в память JVM?
Обновлено: затем вы можете использовать RandomAccessFile или FileChannel для эффективного чтения необходимых частей файла в память JVM.
Изначально он не был буферизован, java немного читал, обрабатывал, затем читал еще немного. При каждом чтении он будет отправлять запрос ввода-вывода, ждать завершения io. Буферизация ввода увеличивает скорость линейно, чем больше буфер, тем быстрее обработка.
Взгляните на Java NIO, он может выполнять гораздо более эффективные операции асинхронного файлового ввода-вывода. См. Ссылку в моем комментарии к вашему вопросу - там довольно хорошее сравнение различных методов.
Вы рассматривали MappedByteBuffer в java.nio? Это над моей головой, но, может быть, это то, что вы ищете.
Я тоже так думал, но похоже, что резервный буфер ByteBuffer - это обычный буфер по-прежнему, поэтому он имеет те же ограничения, что и необработанный буфер.
Есть два вида буфера: один использует байтовый массив, а другой (прямой) использует фиксированное расположение вне кучи Java. К сожалению, размер neight может превышать 2 ГБ. В настоящее время это не исправлено в «дополнительных функциях NIO» (вероятно, в JDK7). Проголосуйте за это. bugs.sun.com/bugdatabase/view_bug.do?bug_id=6347833
Я думаю, что есть 64-битные JVM, которые будут поддерживать нестандартные ограничения.
Вы можете попробовать буферизовать куски.
Я сомневаюсь, что одновременная буферизация более 2 ГБ в любом случае принесет огромную пользу. В зависимости от объема обработки, которую вы выполняете, вы сможете читать почти так же быстро, как и обрабатываете. Чтобы ускорить его, вы можете попробовать использовать двухпоточную модель производитель-потребитель (один поток читает файл и передает данные другому потоку для обработки).
ОС будет кэшировать как можно большую часть файла, поэтому попытка перехитрить диспетчер кеширования, вероятно, не принесет вам многого.
С точки зрения производительности вам будет намного лучше, если байты будут храниться вне JVM (передача огромных фрагментов данных между ОС и JVM относительно медленная). Вы можете достичь этой цели, используя MappedByteBuffer, поддерживаемый прямым блоком памяти.
Вот подходящая статья с практическими рекомендациями: статья
См. stackoverflow.com/questions/140056/… для потенциально связанного вопроса.