Java中的流如何影响内存消耗?
我已经使用了很多次流,但我从来没有读过很多关于它们是如何工作的。除了溪流只是一种隐喻之外,我对它们也不太了解。流只表示字节序列。我不知道它们实际上是如何工作的,我猜在Java中打开文件流会与操作系统交互,操作系统具有向流提供“指针”的功能 基本上,我的问题是流如何影响内存消耗。例如,当您有一个输入流并开始从中读取时,您只会随着读取的字节数增加内存消耗?在Java中打开一个流时,在开始读取之前,您实际上没有加载完整的文件吗?如果您从一个流中读取数据,然后直接写入另一个流,那么您只会随着读取的字节数(以及缓冲区中可能存在的字节数)增加内存?如果在java中向字节数组读取字节,那么会随着文件的大小而增加内存消耗吗Java中的流如何影响内存消耗?,java,memory,Java,Memory,我已经使用了很多次流,但我从来没有读过很多关于它们是如何工作的。除了溪流只是一种隐喻之外,我对它们也不太了解。流只表示字节序列。我不知道它们实际上是如何工作的,我猜在Java中打开文件流会与操作系统交互,操作系统具有向流提供“指针”的功能 基本上,我的问题是流如何影响内存消耗。例如,当您有一个输入流并开始从中读取时,您只会随着读取的字节数增加内存消耗?在Java中打开一个流时,在开始读取之前,您实际上没有加载完整的文件吗?如果您从一个流中读取数据,然后直接写入另一个流,那么您只会随着读取的字节数
听起来可能是个奇怪的问题,但我的理解可能需要一些指导/纠正。谢谢。以上所有答案都是很好的答案,但我不相信它们回答了您最初关于内存消耗的问题 在Java中,可以用多种方式查看流。首先,您有原始流,它是最低级别的流,并以最小的内存开销与底层操作系统(文件、网络等)交互。第二种是缓冲流,可用于包装原始流并添加一些缓冲,从而显著提高性能。流缓冲为缓冲增加了固定的内存开销,可以由应用程序设置。不确定默认值是什么,但可能是最小值,例如32K 第三种类型的流是内存流(即ByteArrayInput/Output),这些流使用的内存与您向它们写入的内存一样多,并且会根据需要增长,直到引用计数变为零(不再使用)时才处理它们的内存。这些流非常有用,但显然会消耗大量内存
最后一种类型实际上不是流,而是一种称为读卡器的I/O类,它提供了与流之间的数据转换的帮助,正如上面所指出的。这些流在未经处理的两种情况下运行。缓冲或内存流,将消耗与正在使用的底层流一样多的内存。从
输入流开始读取后,几乎没有内存开销。打开文件的操作系统开销很小,JVM中分配新对象的开销很小。如果使用默认值为8KB的BufferedInputStream
,也可能会有少量开销
写作的开销很大程度上取决于你的写作目的地。如果它是一个文件输出流
,则与上面描述的相同。如果它是一个ByteArrayOutputStream
,那么在最佳情况下是(2*流长度)字节,在最坏情况下是(3*流长度)字节。也就是说,要将10k字节从InputStream
复制到字节数组中,最坏情况下会分配30k字节
这是因为ByteArrayOutputStream
大小在达到限制后增长了2倍,并且当您调用toByteArray()
时,它还会分配一个新的缓冲区,这对零拷贝有很好的解释。还解释了缓冲区和内存使用情况。