2016-07-07 16 views
10

Vấn đề của tôi:Chờ Chủ đề Resource tiêu thụ

Có một số lượng lớn các chủ đề trong JVM tiêu thụ nhiều tài nguyên (bộ nhớ, CPU), khi đề là TIMED_WAIT nhà nước (không ngủ)> 99,9% thời gian ? Khi các chủ đề được chờ đợi, bao nhiêu chi phí CPU hiện nó chi phí để duy trì chúng nếu có cần thiết ở tất cả?

Câu trả lời cũng áp dụng cho môi trường không liên quan đến JVM (như hạt nhân Linux)?

Bối cảnh:

chương trình của tôi nhận được một số lượng lớn các gói tiêu thụ không gian. Nó lưu trữ số lượng các thuộc tính tương tự trong các gói khác nhau. Sau một khoảng thời gian nhất định sau khi nhận được một gói (có thể là giờ hoặc ngày), gói cụ thể đó sẽ hết hạn và bất kỳ gói nào được đóng góp sẽ được giảm đi.

Hiện tại, tôi đạt được các chức năng này bằng cách lưu trữ tất cả các gói trong bộ nhớ hoặc đĩa. Cứ sau 5 phút, tôi xóa các gói hết hạn khỏi bộ nhớ và quét qua các gói còn lại để đếm các thuộc tính. Phương pháp này sử dụng nhiều bộ nhớ và có độ phức tạp về thời gian xấu (O(n) đối với thời gian và bộ nhớ trong đó n là số gói chưa hết hạn). Điều này làm cho khả năng mở rộng của chương trình khủng khiếp.

Một cách khác để tiếp cận vấn đề này là tăng số thuộc tính mỗi khi gói hàng đến và bắt đầu một chuỗi Timer() làm giảm số thuộc tính sau khi gói hết hạn. Điều này giúp loại bỏ sự cần thiết phải lưu trữ tất cả các gói cồng kềnh và cắt giảm thời gian phức tạp để O(1). Tuy nhiên, điều này tạo ra một vấn đề khác như chương trình của tôi sẽ bắt đầu có số lượng chủ đề O(n), có thể cắt thành hiệu suất. Vì hầu hết các chủ đề sẽ ở trạng thái TIMED_WAIT (Java Timer() gọi phương thức Object.wait(long)) phần lớn vòng đời của chúng, liệu nó có ảnh hưởng đến CPU một cách rất lớn không?

+0

Có bao nhiêu chủ đề bạn đang nghĩ có thể đang đợi? Một vài trăm hoặc hơn có thể không phải là thuế trên hạt nhân để kiểm tra các chủ đề và khi họ cần phải được lên kế hoạch, nhưng nếu bạn đang xếp hàng lên 500 +, bạn có thể muốn xem xét lại cách tiếp cận của bạn .. – txtechhelp

+0

có hơn một vài trăm. Bạn có thể giải thích tại sao hạt nhân phải liên tục kiểm tra các luồng trên 'TIMED_WAIT'? Tôi đã cố gắng tìm thông tin về cách hạt nhân thực hiện điều này một cách cụ thể nhưng không thể tìm thấy bất kỳ thông tin mong muốn nào. – PhotometricStereo

+1

ScheduledExecutor/hàng đợi ưu tiên theo dấu thời gian hết hạn với một chuỗi đơn. – zapl

Trả lời

9

Đầu tiên, một chuỗi Java (hoặc .NET)! = Một chuỗi hạt nhân/hệ điều hành.

Một Java Thread là trình bao bọc cấp cao tóm tắt một số chức năng của chuỗi hệ thống; các loại chủ đề này còn được gọi là chủ đề được quản lý. Ở cấp độ hạt nhân, một luồng chỉ có 2 trạng thái, đang chạy và không chạy. Có một số thông tin quản lý (ngăn xếp, con trỏ hướng dẫn, id chủ đề, vv) mà hạt nhân theo dõi, nhưng không có điều như vậy ở cấp hạt nhân như là một chủ đề trong trạng thái TIMED_WAITING (tương đương .NET với WaitSleepJoin tiểu bang). Những "tiểu bang" chỉ tồn tại trong các bối cảnh đó (một phần lý do tại sao C++ std::thread không có thành viên state).

Có nói rằng, khi một chuỗi được quản lý đang bị chặn, nó đang được thực hiện như vậy trong một vài cách (tùy thuộc vào cách nó đang được yêu cầu bị chặn ở cấp quản lý); các triển khai mà tôi đã thấy trong OpenJDK cho mã luồng sử dụng các semaphores để xử lý các chờ đợi được quản lý (đó là những gì tôi đã thấy trong các khung công tác C++ khác có một loại luồng "được quản lý" cũng như trong .NET Core và sử dụng mutex cho các loại waits/locks khác.

Vì hầu hết các triển khai sẽ sử dụng một số loại cơ chế khóa (như semaphore hoặc mutex), hạt nhân thường làm điều tương tự (ít nhất là câu hỏi của bạn có liên quan); có nghĩa là, hạt nhân sẽ lấy sợi ra khỏi hàng đợi "chạy" và đặt nó vào hàng đợi "chờ" (một context switch).Bắt đầu lập lịch trình và đặc biệt cách nhân xử lý việc thực thi các luồng nằm ngoài phạm vi của Q & A này, đặc biệt là vì bạn đang đặt câu hỏi liên quan đến Java và Java có thể chạy trên một vài kiểu hệ điều hành khác nhau (mỗi xử lý luồng hoàn toàn khác nhau).

Trả lời câu hỏi của bạn trực tiếp hơn:

Có một số lượng lớn các chủ đề trong JVM tiêu thụ nhiều tài nguyên (bộ nhớ, CPU), khi đề là TIMED_WAIT nhà nước (không ngủ)> 99,9% thời gian ?

Để làm điều này, có một vài điều cần lưu ý: chuỗi được tạo sẽ tiêu thụ bộ nhớ cho JVM (ngăn xếp, ID, bộ thu gom rác, v.v.) và hạt nhân tiêu thụ bộ nhớ hạt nhân để quản lý luồng tại hạt nhân cấp độ. Bộ nhớ đó được tiêu thụ không thay đổi trừ khi bạn nói cụ thể như vậy. Vì vậy, nếu thread đang ngủ hoặc chạy, bộ nhớ là như nhau.

CPU là điều sẽ thay đổi dựa trên hoạt động của chuỗi và số lượng chuỗi được yêu cầu (nhớ, luồng cũng tiêu thụ tài nguyên hạt nhân, do đó phải được quản lý ở cấp hạt nhân, do đó, nhiều chuỗi phải được xử lý , thời gian hạt nhân phải được tiêu thụ để quản lý chúng).

Hãy nhớ rằng thời gian hạt nhân lên lịch và chạy chủ đề cực kỳ nhỏ (đó là một phần của điểm thiết kế), nhưng nó vẫn là điều cần xem xét nếu bạn có kế hoạch chạy của chủ đề; Ngoài ra, nếu bạn biết ứng dụng của bạn sẽ chạy trên một CPU (hoặc cụm) chỉ với một vài lõi, bạn càng có ít lõi hơn, thì hạt nhân càng phải chuyển ngữ cảnh, thêm thời gian bổ sung nói chung.

Khi chuỗi đang chờ, chi phí cho CPU là bao nhiêu để duy trì chúng nếu cần thiết?

Không có. Xem ở trên, nhưng chi phí CPU được sử dụng để quản lý các chủ đề không thay đổi dựa trên bối cảnh luồng. CPU bổ sung có thể được sử dụng để chuyển đổi ngữ cảnh và chắc chắn CPU phụ sẽ được sử dụng bởi chính các chủ đề khi hoạt động, nhưng không có thêm "chi phí" cho CPU để duy trì một chuỗi chờ đợi so với chuỗi đang chạy.

Câu trả lời cũng áp dụng cho môi trường không liên quan đến JVM (như hạt nhân Linux)?

Có và không. Như đã nói, các bối cảnh được quản lý thường áp dụng cho hầu hết các loại môi trường đó (ví dụ: Java, .NET, PHP, Lua, v.v.), nhưng các bối cảnh đó có thể khác nhau và thành ngữ luồng và chức năng chung phụ thuộc vào hạt nhân đang được sử dụng. Vì vậy, trong khi một hạt nhân cụ thể có thể xử lý 1000+ chủ đề cho mỗi quá trình, một số có thể có giới hạn cứng, những người khác có thể có các vấn đề khác với số lượng chuỗi cao hơn cho mỗi quá trình; bạn sẽ phải tham khảo thông số kỹ thuật OS/CPU để xem loại giới hạn nào bạn có thể có.

Vì hầu hết các chủ đề sẽ được ở trạng thái TIMED_WAIT (Java của Timer() gọi các Object.wait (phương pháp dài)) đại đa số các vòng đời của chúng, nó vẫn ảnh hưởng đến CPU trong một cách rất lớn ?

Không (một phần của điểm của chủ đề bị chặn), nhưng cần lưu ý: nếu (cạnh trường hợp) tất cả (hoặc> 50%) của các chuỗi đó cần chạy cùng một lúc?Nếu bạn chỉ có một vài chủ đề quản lý các gói của bạn, điều đó có thể không phải là một vấn đề, nhưng nói rằng bạn có 500+; 250 chủ đề tất cả được đánh thức cùng một lúc sẽ gây ra tranh chấp CPU lớn.

Vì bạn chưa đăng bất kỳ mã nào, thật khó để đưa ra đề xuất cụ thể cho kịch bản của bạn, nhưng sẽ có khuynh hướng lưu cấu trúc thuộc tính dưới dạng lớp và giữ lớp đó trong danh sách hoặc bản đồ băm có thể được tham chiếu trong một Timer (hoặc một chuỗi riêng biệt) để xem thời gian hiện tại có khớp với thời gian hết hạn của gói hay không, sau đó mã "hết hạn" sẽ chạy. Điều này giảm số lượng các chủ đề xuống còn 1 và thời gian truy cập là O(1); nhưng một lần nữa, không có mã, gợi ý đó có thể không hoạt động trong kịch bản của bạn.

Hy vọng điều đó sẽ hữu ích.

+0

giải thích tốt đẹp. – hakunami

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