2014-05-13 73 views
5

我注意到下面的代碼使用多線程並保持所有CPU核心在讀取文件時100%左右忙碌。爲什麼scala.io.Source使用所有內核?

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

和我假定以下是相同的

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

我中斷將該代碼作爲我開發機器上Eclipse調試器下一個單元測試(OS X 10.9.2)和表示這些線程:主,ReaderThread,3守護進程系統線程htop顯示如果我在24核心服務器機器(ubuntu 12)的scala控制檯中運行此線程,所有線程都很忙。

問題:

  1. 如何限制使用的線程N多的代碼?
  2. 爲了理解系統性能,您能否向我解釋io.Source中爲什麼以及如何完成這個任務?閱讀源代碼不會有幫助。
  3. 我假設每一行都是按順序讀取的;然而,因爲它使用多線程,所以foreach在多線程中運行?我的調試器似乎告訴我,代碼仍然在主線程中運行。

任何洞察力將不勝感激。

+0

你確定你沒有在所有線程上看到垃圾收集器活動? –

+0

我不這麼認爲,因爲所有24核心在製作清單時接近100%。暫時的物體清潔不應該造成我認爲的沉重負擔。 – user2949165

+3

也許你應該確保使用'-XX:+ UseSerialGC'? –

回答

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

這是我在我的dev的機器,而不是服務器上所捕獲的內存配置文件。我首先執行GC來獲取基線,然後我多次運行上述代碼。伊甸園空間定期清理。內存擺幅約爲20M,而我讀取的較小文件大約爲200M,即每次運行時io.Source會創建10%的臨時對象。

enter image description here

此特徵將創建在共享系統的麻煩。這也將限制我們一次處理多個大文件。這強調了內存,I/O和CPU使用情況,我無法與其他生產作業一起運行我的代碼,但單獨運行它以避免影響系統。

如果您知道在真實的共享生產環境中處理這種情況的更好方法或建議,請告訴我。

+1

嘗試使用'-XX:ParallelGCThreads = n'將GC線程數限制爲更合理的數量。 – wingedsubmariner

相關問題