Scala 进程未正确关闭
Scala Process not closing properly
我有一个启动外部程序的模式,如果它没有及时完成,则将其终止:
val process = command.run(false)
val future = Future(blocking {
process.exitValue()
})
val ret = try {
Await.result(future,
duration.Duration(TIME, duration.SECONDS))
} catch {
case _: TimeoutException =>
process.destroy()
}
但是,出了点问题,进程(或线程?)不断堆积。当我开始时,我有大约 70 个线程(根据 Thread.getAllStackTraces.keySet().size
)。 运行 几个小时后,我的内存超过 310,应用程序崩溃,因为所有内存都用完了。
线程列表如下所示:
3 finalizer waiting
173 scala-execution-context-global-173 waiting
555 scala-execution-context-global-555 waiting
762 scala-execution-context-global-762 waiting
1278 process reaper blocked
1280 simple-error-spawn-thread-760 runnable
1651 simple-output-spawn-thread-943 runnable
636 scala-execution-context-global-636 waiting
86 process reaper blocked
153 scala-execution-context-global-153 waiting
1593 simple-output-spawn-thread-913 runnable
588 scala-execution-context-global-588 waiting
769 scala-execution-context-global-769 waiting
1500 simple-output-spawn-thread-871 runnable
352 scala-execution-context-global-352 waiting
1245 simple-output-spawn-thread-743 runnable
1793 simple-error-spawn-thread-1012 runnable
1586 simple-error-spawn-thread-910 runnable
1801 process reaper runnable
1666 process reaper blocked
395 scala-execution-context-global-395 waiting
1203 simple-output-spawn-thread-721 runnable
...
我从线程内部调用此代码段,未来的执行上下文是 global
。启动的进程是 JVM 进程,最大允许内存大小为 20G,docker 容器有 480G。因为我保证不会同时调用此代码段超过 20 次,所以我应该在任何时候都有 80G 的空闲空间,但显然不是这样。
如何确保启动的进程真正关闭,包括所有关联的内存?
我可以通过更改
来减少线程数量
val process = preped.run(true)
至
val process = preped.run(new ProcessIO(_.close(),_.close(),_.close()))
我现在只有178个线程而且不会再增加了。不过还是大得惊人。
任何 addresses/explains 将接受大量线程而不是这个线程的答案
我有一个启动外部程序的模式,如果它没有及时完成,则将其终止:
val process = command.run(false)
val future = Future(blocking {
process.exitValue()
})
val ret = try {
Await.result(future,
duration.Duration(TIME, duration.SECONDS))
} catch {
case _: TimeoutException =>
process.destroy()
}
但是,出了点问题,进程(或线程?)不断堆积。当我开始时,我有大约 70 个线程(根据 Thread.getAllStackTraces.keySet().size
)。 运行 几个小时后,我的内存超过 310,应用程序崩溃,因为所有内存都用完了。
线程列表如下所示:
3 finalizer waiting
173 scala-execution-context-global-173 waiting
555 scala-execution-context-global-555 waiting
762 scala-execution-context-global-762 waiting
1278 process reaper blocked
1280 simple-error-spawn-thread-760 runnable
1651 simple-output-spawn-thread-943 runnable
636 scala-execution-context-global-636 waiting
86 process reaper blocked
153 scala-execution-context-global-153 waiting
1593 simple-output-spawn-thread-913 runnable
588 scala-execution-context-global-588 waiting
769 scala-execution-context-global-769 waiting
1500 simple-output-spawn-thread-871 runnable
352 scala-execution-context-global-352 waiting
1245 simple-output-spawn-thread-743 runnable
1793 simple-error-spawn-thread-1012 runnable
1586 simple-error-spawn-thread-910 runnable
1801 process reaper runnable
1666 process reaper blocked
395 scala-execution-context-global-395 waiting
1203 simple-output-spawn-thread-721 runnable
...
我从线程内部调用此代码段,未来的执行上下文是 global
。启动的进程是 JVM 进程,最大允许内存大小为 20G,docker 容器有 480G。因为我保证不会同时调用此代码段超过 20 次,所以我应该在任何时候都有 80G 的空闲空间,但显然不是这样。
如何确保启动的进程真正关闭,包括所有关联的内存?
我可以通过更改
来减少线程数量val process = preped.run(true)
至
val process = preped.run(new ProcessIO(_.close(),_.close(),_.close()))
我现在只有178个线程而且不会再增加了。不过还是大得惊人。
任何 addresses/explains 将接受大量线程而不是这个线程的答案