在Java中下载文件时合理的缓冲区大小

在Java中下载文件时合理的缓冲区大小,java,performance,optimization,Java,Performance,Optimization,使用Java传输(不考虑向上/向下)大文件(3-4 Gig)时使用的合理缓冲区大小是多少 byte buf[] = new byte[1024] 或 有时,即使您使用一个大的缓冲区并将其传递给read(byte array[])方法,这也不能保证您将获得一个完整的5me缓冲区。在我的测试中,我发现每次read()调用的平均大小通常为1.5kb。这在性能方面有意义吗?如果有人能给我指出一个更详细地讨论这个问题的资源,我会很高兴 听起来像是从网络连接(TCP)读取数据 1500字节是默认的以太网,

使用Java传输(不考虑向上/向下)大文件(3-4 Gig)时使用的合理缓冲区大小是多少

byte buf[] = new byte[1024]


有时,即使您使用一个大的缓冲区并将其传递给read(byte array[])方法,这也不能保证您将获得一个完整的5me缓冲区。在我的测试中,我发现每次read()调用的平均大小通常为1.5kb。这在性能方面有意义吗?如果有人能给我指出一个更详细地讨论这个问题的资源,我会很高兴

听起来像是从网络连接(TCP)读取数据

1500字节是默认的以太网,这解释了为什么每次读取通常获得1.5KB。通过配置要使用的网络堆栈,MTU通常可以增加到9KB

考虑到这一点,将
buf
设置为大于9KB几乎毫无意义。使用较小的缓冲区(例如超过1KB)可能会或可能不会对性能产生负面影响


在任何情况下,获得明确答案的唯一方法是对各种缓冲区大小进行基准测试。

在我的研究和测试中,在使用Java 6的Linux上从套接字读取数据时,8K是最佳缓冲区大小。如果分配一个大于8K的缓冲区,那将是对空间的浪费。我读到Java的本机调用使用8K缓冲区,这就是为什么8K是最佳的,但我失去了我的参考。有一个bug指向这一事实,但它不是决定性的证据:


也就是说,尝试在您感兴趣的平台上进行实验,您将找到最佳的缓冲区大小。如果你很懒,8K是一个很好的默认值。

Hmz,很好。我还没有真正考虑TCP堆栈的MTU。使用较大的缓冲区将减少Java代码和本机代码之间的切换数量,并且可能会对性能产生影响,与网络数据包大小无关。事实上,如果使用IPv6,也可能会遇到IPv6的巨型帧,这些帧高达4gb(并不是说您今天会使用如此大的帧;但是请记住,IPv4中的巨型帧并不是真正的标准,因此我相信您也会在那里找到更大的帧)。因此,如果真的有什么需要担心的话,我不会硬编码。Afaik Java SDK类的IO缓冲区默认为8kb。我在本地网络的Android设备上试验了缓冲区大小。我发现1024(良好/最佳)、4096(良好)、16384(平均)。8k是最差的。
byte buf[] = new byte[5 * 1024 * 1024]