使用Akka Streams以分块的方式将数据写入文件

3

我使用sttp lib与akka backend从服务器加载文件。以下两种方法之一都会导致加载1Gb文件时显著的内存占用:

import com.softwaremill.sttp._

val file: File = new File(...)

sttp.response(asStream[Source[ByteString, Any]])
.mapResponse { src =>
    src.runWith(FileIO.toPath(file.toPath, options, 0))
}

sttp.response(asFile(file, false))

1GB文件的顺序加载的VisualVM图表。 enter image description here

是否有可能将数据分块写入,并在写入后立即从内存中删除块?

1个回答

1
根据您的情况,您的应用程序不需要大量的内存。有高峰时达到1700 MB,但垃圾收集器运行后堆使用量会降至250 MB。sttp和Akka会创建许多短暂的对象;然而,垃圾收集器会很好地清理您的内存。
我只使用了124MB的内存来运行您的客户端应用程序,以验证它不需要2GB的堆下载1GB的文件。
sbt -mem 124 run

这个应用程序没有崩溃,只是使用了可用的所有内存。 在此输入图像描述

同意。另一方面,使用Apache HttpClient和缓冲区重用的方法不会导致如此过度的内存布局。val rd = new BufferedReader(new InputStreamReader(response.getEntity.getContent), 8192) - morsik
我发现与Apache HttpClient(5-7%,峰值高达20%)相比,Akka使用CPU更加繁重(10-15%,峰值高达30%)。 - morsik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接