gpt4 book ai didi

java - URLConnection.getInputStream() 使用太多内存

转载 作者:可可西里 更新时间:2023-11-01 17:04:56 24 4
gpt4 key购买 nike

我需要在嵌入式系统上下载很多(可能 >5000)相对较小(小于千字节)的文件,所以我没有太多内存。

我写了这段代码,它用于下载每个单独的文件(例如只给出一个文件)

final int BUFFER_LENGTH = 64 * 1024;

URL fileUrl = new URL("http://10.10.0.119:8080/files/a.txt");
File fileToSave = new File("/Users/me/foo/a.txt");

URLConnection connection = fileUrl.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);

InputStream us = connection.getInputStream(); // HOT SPOT (1)

try (BufferedInputStream bs = new BufferedInputStream(us, (int) Math.min(fileSize, 8192))) // HOT SPOT (2)
{
try (FileOutputStream fs = new FileOutputStream(fileToSave))
{
int c;
while ((c = bs.read(data, 0, BUFFER_LENGTH)) != -1)
fs.write(data, 0, c);
}
}

还提一下

private static final int BUFFER_LENGTH = 64 * 1024;
private final byte data[] = new byte[BUFFER_LENGTH]

每个“下载器”实例分配一次,例如一生一次。

因此,我注意到这段代码使用了相对较高 (>200Mb) 的内存量(但所有这些都被 GC 进一步成功释放),我开始使用我的 JProfiler 进行分析。我注意到的是 connection.getInputStream() 在我的程序的生命周期中分配了大约 120Mb,以及分配 BufferedInputStream(我通过将确切的大小到流构造函数中)。

这是我的分析结果。我启用了收集有关 GCed 对象的信息。您可能会注意到,两个最严重的热点是 URLConnection.getInputStream()new BufferedInputStream(),我已经提到了。 enter image description here

在那种情况下我怎样才能减少内存使用量?也许还有其他一些解决方案,例如:

  • 重用这些流
  • 明确指出大小
  • 使用一些不同的方法

非常感谢。

最佳答案

您的应用程序正在使用字节数组作为缓冲区进行读写。这可以分配一次并重新用于所有文件。 (事实上​​,您可能已经在这样做了……尽管您还没有向我们展示实际代码。)

如果您使用大型 byte[] 作为缓冲区进行读写(如您当前所做的那样),则无需使用 BufferedInputStream。 (相对于显式使用缓冲区,使用 BufferedInputStream 不会提高性能。)并且由于每次您创建新的 BufferedInputStream 它都会分配一个新的字节数组作为内部缓冲区,您会发现直接从 InputStream(即 us)读取应该可以节省内存,并且不会降低您的性能。


你的想法是:

Reusing such streams

使用标准 Java API 无法做到这一点。

Explicitly pointing the size

我假设您的意思是创建大小与输入流内容的大小完全匹配的缓冲区。

  1. 如果您回收缓冲区(如我建议的那样),那将无济于事

  2. 它可能无论如何也无济于事。在基本级别,您的代码将从套接字流中读取,并且读取通常不会填充缓冲区。 (从套接字读取将传送当前在本地 TCP 协议(protocol)栈中可用的数据......而不是整个流内容......在一次 read 调用中。)

  3. 超过几千字节后,增加缓冲区大小对性能几乎没有好处。 (您现有的 64 KB 缓冲区大小可能无助于提高吞吐量。)

关于java - URLConnection.getInputStream() 使用太多内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51080010/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com