InputStream是如何在内存中管理的?

Dan*_* B. 3 java

我熟悉InputStream缓冲区的概念以及它们有用的原因(例如,当您需要处理可能比机器RAM大的数据时).

我想知道,InputStream实际上如何携带所有数据?OutOfMemoryError如果有太多数据被转移,可能会导致?

案例场景

如果我从客户端连接到服务器,请求100GB文件,服务器开始使用缓冲区迭代文件的字节,并将字节写回客户端outputStream.write(byte[]).InputStream无论出于何种原因,客户现在还没准备好阅读.服务器会继续无限期地发送文件的字节吗?如果是这样,那么outputstream/inputstream这些机器的RAM 会不会大?

Mat*_*ans 5

InputStream并且OutputStream实现通常不使用大量内存.事实上,在这些类型的单词"流" 的是它并不需要保存数据,因为它是在一个连续的方式访问-以同样的方式,一个流可以不用拿着湖泊和海洋之间的传送水很多水本身.

但"流"并不是描述这一点的最佳词汇.它更像是一个管道,因为当您将数据从服务器传输到客户端时,每个阶段都会从客户端传输反压力,从而控制数据发送的速率.这类似于您的水龙头如何控制通过管道一直到城市水库的流量:

  1. 当客户端读取数据时,它只InputStream在内部(小)缓冲区为空时从操作系统请求更多数据.每个请求只允许传输有限数量的数据;
  2. 当从OS请求数据时,其自己的内部缓冲区清空,并通知服务器有关新数据的空间大小.服务器只能发送这么多(在TCP中称为"流控制":https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Resource_usage)
  3. 在服务器端,当客户端有空间接收数据时,服务器端OS会从其自己的内部缓冲区发送数据.当它自己的内部缓冲区清空时,它允许写入过程用更多数据重新填充它.
  4. 作为服务器端进程write()s OutputStream,OutputStream它将尝试将数据写入OS.当OS缓冲区已满时,它将使服务器进程等待,直到服务器端缓冲区有空间接受新数据.

请注意,慢速客户端可能会使服务器进程花费很长时间.如果您正在编写服务器,并且您无法控制客户端,那么考虑这一点并确保在进行长数据传输时不会占用大量服务器端资源非常重要.