为什么scala.io.Source使用所有核心?

时间:2014-05-13 20:38:38

标签: multithreading scala io parallel-processing

我注意到以下代码使用多个线程并且在读取文件时保持所有CPU核心忙于100%。

scala.io.Source.fromFile("huge_file.txt").toList

我假设以下是相同的

scala.io.Source.fromFile("huge_file.txt").foreach

我在我的开发机器(OS X 10.9.2)上将Eclipse代码作为单元测试中断,并显示以下线程: main,ReaderThread,3 Daemon System Thread 。如果我在24核服务器机器(ubuntu 12)的scala控制台中运行它,htop显示所有线程都忙。

问题:

  1. 如何使用N个线程限制此代码?
  2. 为了理解系统性能,您能解释一下io.Source中的内容,原因和方式吗?阅读来源并没有帮助。
  3. 我假设每一行都按顺序读取;但是,由于它使用多个线程,所以foreach在多个线程中运行?我的调试器似乎告诉我代码仍然在主线程中运行。
  4. 任何见解都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

正如所建议的,我把我的发现放在这里。

我使用以下内容测试带有和不带-J-XX:+UseSerialGC选项

的虚拟代码
$ scala -J-XX:+UseSerialGC
scala> var c = 0
scala> scala.io.Source.fromFile("huge_file.txt").foreach(e => c += e)

在使用该选项之前,我的服务器计算机中的所有24个核心在文件读取期间都处于忙碌状态。选项之后,只有两个线程忙。

enter image description here

这是我在开发机器上捕获的内存配置文件,而不是服务器。我首先执行GC以获得基线,然后我多次运行上面的代码。伊甸园空间定期清理。内存摆动大约是20M,而我读取的较小文件大约是200M,即io.Source每次运行产生10%的临时对象。

enter image description here

这种特性会在共享系统中造成麻烦。这也将限制我们一次处理多个大文件。这会以一种我无法在其他生产作业中运行代码的方式来强调内存,I / O和CPU使用率,但会单独运行以避免此系统受到影响。

如果您在真实的共享生产环境中了解更好的方法或建议来处理这种情况,请告知我们。