Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字,所有写入的内容都保留在内存中_Java_Sockets_Inputstream_Outputstream - Fatal编程技术网

Java套接字,所有写入的内容都保留在内存中

Java套接字,所有写入的内容都保留在内存中,java,sockets,inputstream,outputstream,Java,Sockets,Inputstream,Outputstream,我使用ByteArrayOutputStreams通过套接字发送图像,如下所示 ImageIO.write(image, "gif", byteArrayO); byte [] byteArray = byteArrayO.toByteArray(); Connection.pw.println("" + byteArray.length); int old = Connection.client.getSendBufferSize();

我使用ByteArrayOutputStreams通过套接字发送图像,如下所示

ImageIO.write(image, "gif", byteArrayO);
       byte [] byteArray = byteArrayO.toByteArray();
       Connection.pw.println("" + byteArray.length);
       int old = Connection.client.getSendBufferSize();
       Connection.client.setSendBufferSize(byteArray.length);
       Connection.client.getOutputStream().write(byteArray, 0, byteArray.length);
一切正常,图像最后是130kb,我收到的图像是这样的

int nbrToRead = Integer.parseInt(slave.input.readLine().trim());
            int old = slave.socket.getReceiveBufferSize();
            slave.socket.setReceiveBufferSize(nbrToRead);
            byte[] byteArray = new byte[nbrToRead];
            int nbrRd = 0;
            int nbrLeftToRead = nbrToRead;
            while (nbrLeftToRead > 0) {
                int rd = slave.socket.getInputStream().read(byteArray, nbrRd, nbrLeftToRead);
                if (rd < 0)
                    break;
                nbrRd += rd; 
                nbrLeftToRead -= rd;
            }

            ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);

            BufferedImage img = ImageIO.read(byteArrayI);
int nbrToRead=Integer.parseInt(slave.input.readLine().trim());
int old=slave.socket.getReceiveBufferSize();
slave.socket.setReceiveBufferSize(NBRTREAD);
字节[]字节数组=新字节[NBRTREAD];
int nbrRd=0;
int nbrleefttoread=nbrread;
而(NbLeftToRead>0){
int rd=slave.socket.getInputStream().read(byteArray、nbrRd、nbrleftRead);
if(rd<0)
打破
nbrRd+=rd;
NbleFTREAD-=rd;
}
ByteArrayInputStream byteArrayI=新的ByteArrayInputStream(byteArray);
BuffereImage img=图像IO.read(byteArrayI);
它工作得很好,但是java内存堆中发送的每个映像都会增加50MB。我已尝试设置receivebuffersize,但它仍然保持不变。它在堆中达到最大值,然后停留一段时间,然后停止


如何清除缓冲区,以便在收到字节后处理它们?

我想到了几件事:

  • 您可能持有对某个对象的引用,而该对象并没有被垃圾收集清除。如果做这项工作的类是一个单例,这是一个非常常见的问题
  • 确保对正在使用的任何IO类(如BufferedInputSteam)调用close()

发送对象后,请确保对象已解除引用,因为剩余的引用会将图像保留在内存中。您可以通过将该对象的所有实例设置为
null
来实现这一点

此外,完成后调用
flush()
close()
可以极大地提高内存使用率


我希望这有帮助

您还没有向我们展示您的所有方法,但是在等待下一个映像时,您可能在作用域中有大量内存局部变量

试试这个:

// after you've finished with the input, dereference the memory-heavy objects...
byteArray = null;
byteArrayI = null;
另外,您可以通过调用
System.gc()
并生成线程来“推动”JVM进行垃圾收集(不能使其进行垃圾收集)。如果单独使用空值无效,请尝试添加此选项

System.gc(); // "suggest" garbage collection to execute
Thread.yield(); // I have seen this encourage garbage collection to execute

我敢打赌,
连接
持有一个
对象输出流
。如果这是真的,那么您需要在该流上调用
reset()

我发表了评论,但也将其作为一个答案

当您在内存中创建
buffereImage
s时,必须在处理完它们后调用
flush()
。 我很怀疑你的记忆泄露就是由此而来的

而且,正如马拉奇所说,确保所有东西(缓冲区映像、I/O引用等)都没有任何类型的引用留给
gc
对它们有效


System.gc(),客户端或服务器?连接是保存客户端和套接字的类。当您创建
buffereImage
s时,您也必须对它们调用
flush()
s。可能重复的
flush()
s比
close()
s更重要。ByteArrayInputStream没有flush()方法。ETA:但是flush()可能对发件人有用。。。没有足够的关于代码片段的信息可以看到。我很抱歉!我现在正在测试关闭它,我以为它会关闭连接,但它只是关闭bytearrayoutputstream的本地实例。它在发送图像的一侧泄漏。不是接收器。现在我知道问题出在哪里了。几乎完全正确。我不确定我是否应该提出一个新问题,所以:当我创建bytearrayoutputstream的新实例并使用ImageIO.write将图像写入其中时,它首先在内存中增加100 mb,然后缓慢增加,几次之后它就停止工作了。是的,我冲洗、重置然后关闭它。是的。必须在发送端关闭()
,否则无法完成发送。请注意,
close()
也会自动执行
flush()
,因此无需同时调用
flush()
。不。我将所有内容写入这个bytestream,然后将其“正常”写入套接字。这不是问题。很好。但当我对它进行映像IO时,内存会增加。当我停止使用流或关闭流时,它不会消失。不,我使用socket.getOutputStream()和socket.getInputStream()