Проблема Java OutOfMemory при передаче байтового массива - PullRequest
0 голосов
/ 31 марта 2011

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

imageBytes = //read from socket.
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage bufferedImage = ImageIO.read(in);
Image image = Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource());
Image scaledImage = image.getScaledInstance(rmdPanel.getWidth(),rmdPanel.getHeight() ,Image.SCALE_FAST);
Graphics graphics = rmdPanel.getGraphics();
graphics.drawImage(scaledImage, 0, 0, rmdPanel.getWidth(),rmdPanel.getHeight(),rmdPanel);

Я также храню imagebytes до следующего изображения (для сравнения). Теперь я получаю исключение Java из памяти в этом коде (при получении байтового массива). У меня размер кучи 128 мб-512 мб. Отправленные байты изображения не более 3 МБ.

Ответы [ 3 ]

1 голос
/ 31 марта 2011

(вы не показываете код связи, так что я просто догадываюсь), если вы используете ObjectInputStream / ObjectOutputStream над потоками сокетов, вы должны знать, что они кэшируют объекты, отправленные по проводам (чтобы избежать повторной отправки те же данные). иногда это хорошая функция, но она может вызвать проблемы, если объекты удерживаются слишком долго. вам необходимо периодически вызывать метод reset () для ObjectOutputStream, чтобы очистить этот кэш (в вашем случае, возможно, после каждой отправки изображения).

Конечно, самый надежный способ решить эту проблему - подключить профилировщик памяти и посмотреть, что использует всю память (или проанализировать дамп кучи).

1 голос
/ 31 марта 2011
imageBytes = //read from socket.
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage bufferedImage = ImageIO.read(in);

Зачем читать байты изображения в массив? Тебе это не нужно. Это будет стоить вам как минимум одну дополнительную копию данных, возможно, две, если ByteArrayInputStream скопирует байтовый массив. Просто выполните ImageIO.read () прямо из сокета.

0 голосов
/ 31 марта 2011

I думаю, ImageIO.read (...) выполняет какое-то кэширование изображений или их входных потоков, так что это может привести к нехватке памяти при продолжении чтения изображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...