2014-05-13 16 views
5

Tôi nhận thấy rằng đoạn mã sau sử dụng nhiều luồng và giữ cho tất cả các lõi CPU bận khoảng 100% trong khi nó đang đọc tệp.Tại sao scala.io.Source sử dụng tất cả các lõi?

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

và tôi giả sử sau đây là cùng

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

tôi gián đoạn mã này như một thử nghiệm đơn vị dưới debugger Eclipse trên máy dev của tôi (OS X 10.9.2) và hiển thị những chủ đề: chính, ReaderThread, 3 Daemon Hệ thống Chủ đề. htop cho thấy tất cả các chủ đề đang bận nếu tôi chạy điều này trong một bàn điều khiển scala trong một máy chủ 24 lõi (ubuntu 12).

Câu hỏi:

  1. Làm thế nào để hạn chế mã này về việc sử dụng số N của đề?
  2. Để hiểu được hiệu suất của hệ thống, bạn có thể giải thích cho tôi điều gì, tại sao và cách thực hiện điều này trong io.Source? Đọc nguồn không giúp ích gì.
  3. Tôi cho rằng mỗi dòng được đọc theo thứ tự; tuy nhiên, vì nó đang sử dụng nhiều chủ đề, nên chạy foreach trong nhiều luồng? Trình gỡ lỗi của tôi dường như cho tôi biết rằng mã vẫn chạy trong chuỗi chính.

Mọi thông tin chi tiết sẽ được đánh giá cao.

+0

Bạn có chắc chắn bạn không thấy hoạt động thu gom rác trên tất cả các chuỗi không? –

+0

Tôi không nghĩ như vậy là tất cả 24 lõi gần 100% khi tạo danh sách. Làm sạch đối tượng tạm thời không nên tạo tải nặng như vậy tôi tin. – user2949165

+3

Có lẽ bạn nên đảm bảo với '-XX: + UseSerialGC'? –

Trả lời

0

Như đã đề xuất, tôi đặt các phát hiện của mình ở đây.

tôi sử dụng sau đây để kiểm tra mã giả của tôi có và không có tùy chọn -J-XX:+UseSerialGC

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

Trước khi tôi sử dụng tùy chọn, tất cả 24 lõi trong máy máy chủ của tôi đang bận rộn trong thời gian tập đọc. Sau tùy chọn, chỉ có hai luồng đang bận.

enter image description here

Đây là hồ sơ cá nhân ký ức tôi bắt trên máy dev của tôi, không phải máy chủ. Lần đầu tiên tôi thực hiện GC để lấy đường cơ sở, sau đó tôi chạy mã trên nhiều lần. Không gian Eden được dọn dẹp định kỳ. Việc xoay bộ nhớ là khoảng 20M, trong khi tệp nhỏ hơn tôi đọc là khoảng 200M tức là io.Source tạo 10% đối tượng tạm thời cho mỗi lần chạy.

enter image description here

đặc điểm này sẽ tạo ra rắc rối trong một hệ thống chia sẻ. Điều này cũng sẽ hạn chế chúng tôi xử lý nhiều tệp lớn cùng một lúc. Điều này nhấn mạnh bộ nhớ, i/o và việc sử dụng CPU theo cách mà tôi không thể chạy mã của tôi với các công việc sản xuất khác, nhưng chạy nó một cách riêng biệt để tránh tác động hệ thống này.

Nếu bạn biết cách tốt hơn hoặc đề xuất xử lý tình huống này trong môi trường sản xuất được chia sẻ thực, vui lòng cho tôi biết.

+1

Hãy thử sử dụng '-XX: ParallelGCThreads = n' để giới hạn số lượng các chuỗi GC đến một số hợp lý hơn. – wingedsubmariner

Các vấn đề liên quan