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 нет метода, позволяющего уменьшить буфер. Сброс меняет положение в буфере.

Решение для вас состоит в том, чтобы

  1. Используйте конструктор, чтобы указать размер буфера перед использованием. Когда вы пишете большие объекты в поток, это сэкономит много памяти и предотвратит исключения OOM.
  2. Если вы хотите повторно использовать ваш объект BAOS, вызовите сброс. Это сделает следующую запись начала в начале буфера.
  3. Единственный способ освободить память - удалить все ссылки на нее. В приведенном выше коде вы бы сказали, что byteArray=null;
Другие вопросы по тегам