传输字节数组时出现 Java OutOfMemory 问题
我正在编写远程桌面应用程序。因此,我通过套接字将图像作为字节数组从一台机器传输到另一台机器。接收字节数组后,我将其转换为图像并在面板上绘制。代码大致如下所示,
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);
我还存储图像字节直到下一个图像出现(用于比较)。现在我在这段代码中遇到了java内存不足异常(在接收字节数组时)。我的堆大小为 128 mb-512 mb。发送的图像字节最大为 3mb。
I am writing remote desktop application. So I am transferring Images from one machine to another machine as byte array through socket. After receiving byte array I convert it into image and draw on a panel. Code looks approximately like below
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);
I also store imagebytes till next image comes(for comparison). Now I am getting java out of memory exception in this code(while receiving byte array). I have heap size of 128 mb-512 mb. Image bytes sent are maximum 3mb.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
(您没有显示通信代码,所以我只是猜测)如果您在套接字流上使用 ObjectInputStream/ObjectOutputStream,您需要注意它们缓存通过线路发送的对象(以避免重新发送相同的数据) 。有时,这是一个很好的功能,但如果物体持有时间过长,它可能会导致问题。您需要定期调用 ObjectOutputStream 上的 Reset() 来清除此缓存(在您的情况下,可能在每次发送图像后)。
当然,解决这个问题最可靠的方法是附加一个内存分析器并查看什么在使用所有内存(或分析堆转储)。
(you don't show the communication code, so i'm just guessing) if you are using ObjectInputStream/ObjectOutputStream over the socket streams, you need to be aware that they cache objects sent over the wire (to avoid resending the same data). sometimes, this is a nice feature, but it can cause problems if objects are held too long. you need to periodically call reset() on the ObjectOutputStream to clear this cache (in your case, possibly after every image send).
of course, the surest way to solve this problem is to attach a memory profiler and see what's using all the memory (or analyze a heap dump).
为什么将图像字节读入数组?你不需要那个。它至少会花费您一份额外的数据副本,如果 ByteArrayInputStream 复制字节数组,则可能会花费两份。只需直接从套接字执行 ImageIO.read() 即可。
Why read the image bytes into an array? You don't need that. It is costing you at least one extra copy of the data, maybe two if the ByteArrayInputStream copies the byte array. Just do ImageIO.read() straight from the socket.
我认为 ImageIO.read(...) 对图像或其输入流进行某种缓存,因此当您继续读取图像时可能会导致内存不足。
I think ImageIO.read(...) does some sort of caching of images or their input streams so that may be causing you to run out of memory as you keep reading images.