Java BufferedArrayOutputStream просачивается в память
Я сделал новый вопрос, потому что это отличается от моей последней темы. Теперь я знаю, в чем проблема точнее.
Я создаю новый bytearrayoutputstream
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
Ничего особенного. Затем, когда я пишу изображение, таким образом,
ImageIO.write(image, "gif", byteArray);
память увеличивается сначала на 100 мегабайт, не в затмении, а в "реальности". Затем он медленно увеличивается после этого каждый раз, когда я записываю новое изображение в этот поток ИЛИ другое!!
и через некоторое время он перестает работать и вроде как падает.
Я пытался закрыть его и все такое, очистить, сбросить все, но это все еще утечка памяти. Я хочу, чтобы он уходил из памяти, когда я прекращал использовать byteArray или обнулял его.
System.gc();
не поможет в этом случае.
Пожалуйста, помогите мне, и все, что вам нужно знать, я отвечу, и, пожалуйста, вернитесь и ответьте:)
4 ответа
То, что вы делаете, не имеет никакого смысла. Вы извлекаете изображение из памяти и снова помещаете его в память, на этот раз в виде байтового массива.
Вы должны поместить это изображение в файл или отправить по сети. Или, если вы хотите просто сохранить копию, скопируйте изображение (не байтовый массив!), Как я описал здесь: Ошибка в использовании Object.clone()
Ваш шаблон использования должен быть таким:
while( keepRunning) {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
ImageIO.write(image, "gif", byteArray);
}
Если вы сделаете это быстрее, чем JVM сможет собрать мусор, вы в конечном итоге получите очень длинную паузу GC или исключение OutOfMemory.
Вы пробовали это:
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
baos.flush();
byte[] imageBytes = baos.toByteArray();
baos.close();
}catch(Exception ex){
System.out.println(ex.getMessage());
}
Пожалуйста, обратитесь к аналогичному ответу, который я разместил на другой вопрос ByteArrayOutputStream.
В ByteArrayOutputStream нет метода, позволяющего уменьшить буфер. Сброс меняет положение в буфере.
Решение для вас состоит в том, чтобы
- Используйте конструктор, чтобы указать размер буфера перед использованием. Когда вы пишете большие объекты в поток, это сэкономит много памяти и предотвратит исключения OOM.
- Если вы хотите повторно использовать ваш объект BAOS, вызовите сброс. Это сделает следующую запись начала в начале буфера.
- Единственный способ освободить память - удалить все ссылки на нее. В приведенном выше коде вы бы сказали, что byteArray=null;