Как избежать OutOfMemoryError при использовании Bytebuffers и НИО?

голоса
3

Я использую ByteBuffersи FileChannelsдля записи двоичных данных в файл. При выполнении , что для больших файлов или последовательно для нескольких файлов, я получаю OutOfMemoryErrorисключение. Я читал в другом месте , что при использовании Bytebuffersс NIO сломано , и его следует избегать. Кто - нибудь из вас уже сталкивались с такой проблемой и нашел решение для эффективного сохранения больших объемов двоичных данных в файл в Java?

Есть вариант JVM -XX:MaxDirectMemorySizeпуть?

Задан 26/08/2008 в 18:23
источник пользователем
На других языках...                            


6 ответов

голоса
6

Я бы сказал, не создают огромный ByteBuffer, который содержит все данные сразу. Создание гораздо меньше ByteBuffer, заполнить его данными, а затем записать эти данные в FileChannel. Затем сбросить ByteBuffer и продолжать, пока все данные не будут записаны.

Ответил 26/08/2008 d 18:26
источник пользователем

голоса
4

Проверьте в Java отображенных Byte Буферы , также известную как «прямые буфера». В принципе, этот механизм использует виртуальную систему подкачки памяти операционной системы на «карту» свой буфер непосредственно на диск. ОС будет управлять перемещением байт / с диска и памяти автоматически волшебно, очень быстро, и вам не придется беспокоиться об изменении настройки виртуальной машины. Это также позволит вам воспользоваться преимуществами улучшенной производительности NiO над традиционной Java поток на основе ввода / вывода, без каких - либо странных писак.

Только два уловы, что я могу думать о том, являются:

  1. На 32-битной системе, вы ограничены только под 4 Гб общей для всех отображенных байт буфера . (Это на самом деле предел для моего приложения, и теперь я бег на 64-разрядных архитектурах.)
  2. Реализация является JVM специфичны и не является обязательным требованием. Я использую JVM Sun и нет никаких проблем, но YMMV.

Кирк Пеппердин (несколько известный гуру производительности Java) участвует с веб - сайтом, www.JavaPerformanceTuning.com, что есть еще некоторые детали MBB: НИО Советы Performance

Ответил 26/08/2008 d 19:01
источник пользователем

голоса
1

Если доступ к файлам в случайном порядке (читать здесь, пропустить, там писать, двигаться назад) , то у вас есть проблемы ;-)

Но если вы только писать большие файлы, вы должны серьезно рассмотреть возможность использования потоков. java.io.FileOutputStream может быть использован непосредственно для записи файла байт за байтом или завернутый в любом другом потоке (т.е. DataOutputStream, ObjectOutputStream) для удобства написания поплавков, Интс, струнные или даже serializeable объектов. Аналогичные классы для чтения файлов.

Потоки предлагают вам удобство манипулирования сколь угодно больших файлов в (почти) сколь угодно малой памяти . Они предпочтительны способ доступа к файловой системе в подавляющем большинстве случаев.

Ответил 26/08/2008 d 18:35
источник пользователем

голоса
0

Это может зависеть от конкретного поставщика JDK и версии.

Существует ошибка в GC в некотором Sun JVM. Нехватка прямого памяти не вызовет GC в основной куче, но прямая память придавленный мусора прямых ByteBuffers в основной куче. Если основная куча в основном пустая, они многие не собираются в течение длительного времени.

Это может сжечь вас, даже если вы не используете прямые буфера самостоятельно, потому что JVM может создавать прямые буфера от вашего имени. Например, написание непрямого ByteBuffer к SocketChannel создает прямой буфер под одеялом, чтобы использовать для фактической операции ввода / вывода.

Чтобы обойти эту проблему, чтобы использовать небольшое количество прямых буферов самостоятельно, и держать их вокруг для повторного использования.

Ответил 26/09/2008 d 16:14
источник пользователем

голоса
0

Использование transferFrom метод должен помочь с этим, если вы пишите в канал постепенно , а не все сразу , как и предыдущие ответы также указывают.

Ответил 26/08/2008 d 19:51
источник пользователем

голоса
0

Предыдущие два ответа, кажется довольно разумным. Что же касается, будет ли переключатель командной работы, это зависит от того, насколько быстро вашего использования памяти достигнет предела. Если у вас нет достаточно оперативной и виртуальной памяти, доступной по меньшей мере в три раза доступной памяти, то вам нужно будет использовать один из альтернативных предложений, приведенных.

Ответил 26/08/2008 d 19:02
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more