【问题标题】:Sensible buffer size when downloading files in Java用 Java 下载文件时的合理缓冲区大小
【发布时间】:2011-11-10 15:48:09
【问题描述】:

使用 Java 传输(不考虑 UP/DOWN)大文件(3-4 gigs)时使用的合理缓冲区大小是多少?

byte buf[] = new byte[1024]

byte buf[] = new byte[5 * 1024 * 1024]

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

【问题讨论】:

    标签: java performance optimization


    【解决方案1】:

    在我的研究和测试中,8K 是使用 Java 6 从 Linux 上的套接字读取时的最佳缓冲区大小。如果分配的缓冲区大于 8K,那只会浪费空间。我读过 Java 进行的本机调用使用 8K 缓冲区,这就是为什么 8K 是最佳但我失去了参考。有一个错误指向这个事实,但它不是确凿的证据:http://bugs.sun.com/view_bug.do?bug_id=6444633

    也就是说,尝试在您有兴趣部署的平台上进行试验,您会发现最佳缓冲区大小。如果你很懒,8K 是一个很好的默认值。

    【讨论】:

      【解决方案2】:

      听起来您正在从网络连接(TCP?)读取数据

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

      考虑到这一点,几乎可以肯定将buf 设置为大于 9KB 是没有意义的。使用较小的缓冲区(比如超过 1KB)可能会对性能产生负面影响,也可能不会。

      无论如何,获得明确答案的唯一方法是对各种缓冲区大小进行基准测试。

      【讨论】:

      • 嗯,好点。我还没有真正考虑 TCP 堆栈的 MTU。
      • 使用较大的缓冲区将减少 Java 代码和本机代码之间的切换次数,并且可能会对性能产生影响,与网络数据包大小无关。
      • 实际上,如果您使用 IPv6,您也可能会遇到 IPv6 的巨型帧,这些帧最大为 4gb(不是说您今天会使用这么大的帧;但请记住,巨型帧在 IPv4 中并不是真正的标准,所以我相信你也可以在那里找到更大的帧)。因此,如果这确实令人担心,我不会对其进行硬编码。 Afaik Java SDK 类的 IO 缓冲区默认为 8kb。
      • 我已经在本地网络中试验了 Android 设备的缓冲区大小。我找到了 1024(好/最好)、4096(好)、16384(平均)。 8k 是最差的。
      猜你喜欢
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 2023-04-05
      相关资源
      最近更新 更多