当 运行 大型外部进程时,Scala 会产生 GC 开销
Scala hit GC overhead when running large external process
我有一个外部程序可以生成我需要的一些数据。通常,我将它的输出重定向到一个文件,然后从我的 Scala 应用程序中读取它,例如
app.exe > output.data
现在,我想整合流程,所以我做了
val stream = "app.exe" lineStream
stream foreach { line => doWork(_) }
不幸的是,一段时间后我遇到了 GC 开销 异常。 app.exe
可能会生成非常大的输出文件,例如超过 100MB。所以我认为在流式传输期间,Scala 已 creating/destroying line
字符串实例数千次,并导致开销。
我知道我可以调整 JVM 变量来增加 GC 开销限制。但我正在寻找一种不需要创建很多小 line
实例的方法。
问题可能是由于记忆化引起的,这是以这种方式对流进行 foreach 的副作用。实际上,您正在将整个文件植根于内存中。
在此处查看大量有关如何避免这种情况的信息:http://blog.dmitryleskov.com/programming/scala/stream-hygiene-i-avoiding-memory-leaks/
具体来说,您违反了规则 #1。尝试将您的流定义为 def
,而不是 val
.
我有一个外部程序可以生成我需要的一些数据。通常,我将它的输出重定向到一个文件,然后从我的 Scala 应用程序中读取它,例如
app.exe > output.data
现在,我想整合流程,所以我做了
val stream = "app.exe" lineStream
stream foreach { line => doWork(_) }
不幸的是,一段时间后我遇到了 GC 开销 异常。 app.exe
可能会生成非常大的输出文件,例如超过 100MB。所以我认为在流式传输期间,Scala 已 creating/destroying line
字符串实例数千次,并导致开销。
我知道我可以调整 JVM 变量来增加 GC 开销限制。但我正在寻找一种不需要创建很多小 line
实例的方法。
问题可能是由于记忆化引起的,这是以这种方式对流进行 foreach 的副作用。实际上,您正在将整个文件植根于内存中。
在此处查看大量有关如何避免这种情况的信息:http://blog.dmitryleskov.com/programming/scala/stream-hygiene-i-avoiding-memory-leaks/
具体来说,您违反了规则 #1。尝试将您的流定义为 def
,而不是 val
.