我正在编写远程桌面应用程序。所以我将图像从一台机器传输到另一台机器作为字节数组通过socket。接收到字节数组后,我将其转换为图像并在面板上绘图。代码看起来大致如下
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 mb- 512 mb。发送的图像字节最大为3mb。请帮我解决问题。谢谢你的时间。
答案 0 :(得分:1)
imageBytes = //read from socket.
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage bufferedImage = ImageIO.read(in);
为什么要将图像字节读入数组?你不需要那个。如果ByteArrayInputStream复制字节数组,则至少需要花费一个额外的数据副本,可能需要两个。直接从套接字执行ImageIO.read()。
答案 1 :(得分:1)
(你没有显示通信代码,所以我只是猜测)如果你在套接字流上使用ObjectInputStream / ObjectOutputStream,你需要知道他们缓存通过网络发送的对象(以避免重新发送相同的数据)。有时,这是一个很好的功能,但如果对象持有太长时间,它可能会导致问题。您需要定期调用ObjectOutputStream上的reset()来清除此缓存(在您的情况下,可能在每次图像发送后)。
当然,解决此问题的最可靠方法是附加内存分析器并查看使用所有内存的内容(或分析堆转储)。
答案 2 :(得分:0)
我认为 ImageIO.read(...)会对图像或其输入流进行某种缓存,因此在您继续阅读图像时可能会导致内存不足。