Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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_Memory - Fatal编程技术网

Java中的流如何影响内存消耗?

Java中的流如何影响内存消耗?,java,memory,Java,Memory,我已经使用了很多次流,但我从来没有读过很多关于它们是如何工作的。除了溪流只是一种隐喻之外,我对它们也不太了解。流只表示字节序列。我不知道它们实际上是如何工作的,我猜在Java中打开文件流会与操作系统交互,操作系统具有向流提供“指针”的功能 基本上,我的问题是流如何影响内存消耗。例如,当您有一个输入流并开始从中读取时,您只会随着读取的字节数增加内存消耗?在Java中打开一个流时,在开始读取之前,您实际上没有加载完整的文件吗?如果您从一个流中读取数据,然后直接写入另一个流,那么您只会随着读取的字节数

我已经使用了很多次流,但我从来没有读过很多关于它们是如何工作的。除了溪流只是一种隐喻之外,我对它们也不太了解。流只表示字节序列。我不知道它们实际上是如何工作的,我猜在Java中打开文件流会与操作系统交互,操作系统具有向流提供“指针”的功能

基本上,我的问题是流如何影响内存消耗。例如,当您有一个输入流并开始从中读取时,您只会随着读取的字节数增加内存消耗?在Java中打开一个流时,在开始读取之前,您实际上没有加载完整的文件吗?如果您从一个流中读取数据,然后直接写入另一个流,那么您只会随着读取的字节数(以及缓冲区中可能存在的字节数)增加内存?如果在java中向字节数组读取字节,那么会随着文件的大小而增加内存消耗吗


听起来可能是个奇怪的问题,但我的理解可能需要一些指导/纠正。谢谢。

以上所有答案都是很好的答案,但我不相信它们回答了您最初关于内存消耗的问题

在Java中,可以用多种方式查看流。首先,您有原始流,它是最低级别的流,并以最小的内存开销与底层操作系统(文件、网络等)交互。第二种是缓冲流,可用于包装原始流并添加一些缓冲,从而显著提高性能。流缓冲为缓冲增加了固定的内存开销,可以由应用程序设置。不确定默认值是什么,但可能是最小值,例如32K

第三种类型的流是内存流(即ByteArrayInput/Output),这些流使用的内存与您向它们写入的内存一样多,并且会根据需要增长,直到引用计数变为零(不再使用)时才处理它们的内存。这些流非常有用,但显然会消耗大量内存


最后一种类型实际上不是流,而是一种称为读卡器的I/O类,它提供了与流之间的数据转换的帮助,正如上面所指出的。这些流在未经处理的两种情况下运行。缓冲或内存流,将消耗与正在使用的底层流一样多的内存。

输入流开始读取后,几乎没有内存开销。打开文件的操作系统开销很小,JVM中分配新对象的开销很小。如果使用默认值为8KB的
BufferedInputStream
,也可能会有少量开销

写作的开销很大程度上取决于你的写作目的地。如果它是一个
文件输出流
,则与上面描述的相同。如果它是一个
ByteArrayOutputStream
,那么在最佳情况下是(2*流长度)字节,在最坏情况下是(3*流长度)字节。也就是说,要将10k字节从
InputStream
复制到字节数组中,最坏情况下会分配30k字节


这是因为
ByteArrayOutputStream
大小在达到限制后增长了2倍,并且当您调用
toByteArray()

时,它还会分配一个新的缓冲区,这对零拷贝有很好的解释。还解释了缓冲区和内存使用情况。