Java VM có thể hỗ trợ bao nhiêu luồng?


212

Java VM có thể hỗ trợ bao nhiêu luồng? Điều này thay đổi theo nhà cung cấp? bởi hệ điều hành? những yếu tố khác?

Câu trả lời:


170

Điều này phụ thuộc vào CPU bạn đang sử dụng, trên HĐH, vào các quy trình khác đang làm gì, trên bản phát hành Java nào bạn đang sử dụng và các yếu tố khác. Tôi đã thấy một máy chủ Windows có> 6500 Chủ đề trước khi đưa máy xuống. Tất cả các chủ đề đã không làm bất cứ điều gì, tất nhiên. Khi máy đạt khoảng 6500 Chủ đề (bằng Java), toàn bộ máy bắt đầu gặp sự cố và không ổn định.

Kinh nghiệm của tôi cho thấy Java (các phiên bản gần đây) có thể vui vẻ tiêu thụ nhiều Chủ đề như chính máy tính có thể lưu trữ mà không gặp sự cố.

Tất nhiên, bạn phải có đủ RAM và bạn phải khởi động Java với đủ bộ nhớ để làm mọi thứ mà Chủ đề đang làm và có một ngăn xếp cho mỗi Chủ đề. Bất kỳ máy nào có CPU hiện đại (vài thế hệ AMD hoặc Intel gần đây nhất) và có bộ nhớ 1 - 2 Gig (tùy thuộc vào hệ điều hành) có thể dễ dàng hỗ trợ JVM với hàng ngàn Chủ đề.

Nếu bạn cần một câu trả lời cụ thể hơn câu này, cách tốt nhất của bạn là hồ sơ.


86

Ừm, rất nhiều.

Có một vài thông số ở đây. VM cụ thể, cộng với thường có các tham số thời gian chạy trên VM. Điều đó phần nào được điều khiển bởi hệ điều hành: HĐH cơ bản có hỗ trợ gì cho các luồng và nó có những hạn chế gì đối với chúng? Nếu VM thực sự sử dụng các luồng cấp độ hệ điều hành, thì luồng xử lý màu đỏ / luồng xanh cũ tốt.

"Hỗ trợ" nghĩa là gì một câu hỏi khác. Nếu bạn viết một chương trình Java giống như

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(và đừng phàn nàn về các chi tiết cú pháp nhỏ, tôi đang uống tách cà phê đầu tiên của mình), sau đó bạn chắc chắn sẽ mong đợi có được hàng trăm hoặc hàng ngàn chuỗi hoạt động. Nhưng việc tạo một Chủ đề tương đối tốn kém và chi phí lập lịch có thể trở nên khó khăn; không rõ ràng rằng bạn có thể có những chủ đề đó làm bất cứ điều gì hữu ích.

Cập nhật

Được rồi, không thể cưỡng lại. Đây là chương trình thử nghiệm nhỏ của tôi, với một vài chỉnh sửa:

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

Trên OS / X 10.5.6 trên Intel và Java 6 5 (xem bình luận), đây là những gì tôi nhận được

Chủ đề mới # 2547
Chủ đề mới # 2548
Chủ đề mới # 2549
Không thể tạo chủ đề: 5
Chủ đề mới # 2550
Ngoại lệ trong luồng "chính" java.lang.OutOfMemoryError: không thể tạo luồng gốc mới
        tại java.lang.Thread.start0 (Phương thức gốc)
        tại java.lang.Thread.start (Thread.java giáp92)
        tại DieLikeADog.main (DieLikeADog.java:6)

10
Bạn đã khởi động JVM với bao nhiêu bộ nhớ? Đó là vấn đề.
Eddie

10
Bản cập nhật Java 6 13, Ubuntu 8.10 32 Bit, ram 4Gig, Cài đặt JVM mặc định = 6318 Chủ đề.
Steve K

9
Heh, chơi với kích thước ngăn xếp chủ đề. java -Xss100k cho phép tôi tạo các luồng 19702 trong Linux.
Steve K

21
java -Xss50k đã cho tôi khoảng 32k chủ đề. Điều đó đã vượt quá 4g ram của tôi. Tôi đã phải dừng một số quy trình đang chạy để lấy lại đủ bộ nhớ trên máy của mình để rẽ nhánh một quy trình mới để tiêu diệt java;) - thời điểm tốt.
Steve K

21
Sử dụng Java 7 trên windows 7 Tôi chỉ tạo được 200.000 luồng trước khi hệ thống của tôi chết. Trình quản lý tác vụ cho thấy quá trình sử dụng 8GB RAM. Không chắc tại sao nó lại dừng ở đó, mặc dù ... tôi có 12GB RAM trên máy tính. Vì vậy, điều này có thể được nhấn một số giới hạn khác.
Dobes Vandermeer

50

Sau khi đọc bài đăng của Charlie Martin, tôi tò mò về việc liệu kích thước heap có làm thay đổi số lượng chủ đề bạn có thể tạo hay không và tôi hoàn toàn chết lặng trước kết quả.

Sử dụng JDK 1.6.0_11 trên Vista Home Premium SP1, tôi đã thực thi ứng dụng thử nghiệm của Charlie với các kích cỡ heap khác nhau, từ 2 MB đến 1024 MB.

Ví dụ, để tạo một đống 2 MB, tôi sẽ gọi JVM bằng các đối số -Xms2m -Xmx2m.

Đây là kết quả của tôi:

2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads

Vì vậy, yeah, kích thước heap chắc chắn có vấn đề. Nhưng mối quan hệ giữa kích thước heap và số lượng luồng tối đa là tỷ lệ thuận.

Thật là kỳ lạ.


11
sẽ có ý nghĩa nếu MACHI chủ đề được đưa ra một đống kích thước đó.
Thorbjørn Ravn Andersen

1
Hãy cẩn thận: máy của tôi không có 2583 GB RAM. Hoặc trao đổi. Và JVM không phân bổ không gian vùng heap luồng. Vì vậy, không thể nào ...
benjismith

49
Kích thước heap giảm không gian địa chỉ có sẵn cho ngăn xếp. Không gian địa chỉ 256K / stack có ý nghĩa.
Tom Hawtin - tackline

1
Vâng, điều này cho thấy điều tương tự pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby

39

Tôi biết câu hỏi này khá cũ nhưng chỉ muốn chia sẻ những phát hiện của tôi.

Máy tính xách tay của tôi có thể xử lý chương trình sinh ra các 25,000luồng và tất cả các luồng đó ghi một số dữ liệu trong cơ sở dữ liệu MySql trong khoảng thời gian thông thường là 2 giây.

Tôi chạy chương trình này với 10,000 threadscho 30 minutes continuouslythì cũng hệ thống của tôi đã ổn định và tôi đã có thể làm hoạt động bình thường khác như duyệt web, mở, đóng các chương trình khác, vv

Với 25,000 threadshệ thống slows downnhưng nó vẫn đáp ứng.

Với 50,000 threadshệ thống stopped respondingngay lập tức và tôi phải khởi động lại hệ thống của mình một cách thủ công.

Chi tiết hệ thống của tôi như sau:

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

Trước khi chạy tôi đặt đối số jvm -Xmx2048m.

Hy vọng nó giúp.


2
"Chậm lại" âm thanh như trao đổi.
Thorbjørn Ravn Andersen

Cảm ơn. Nó là một cỗ máy khá chắc chắn và hoạt động tốt trong gần 8 năm cho đến khi đột nhiên nó ngừng khởi động. Tôi mới cài đặt Ubuntu trên nó thay vì Windows và nó lại bắt đầu khủng hoảng số :)
Shekhar

Bộ đôi Fried core 2 với gia vị
ubfox

31

Các lý thuyết tối đa tuyệt đối thường là một quá trình không gian địa chỉ dùng chia cho thread stack kích thước (mặc dù trong thực tế, nếu tất cả các bộ nhớ của bạn được dành riêng cho ngăn xếp chủ đề, bạn sẽ không có một chương trình làm việc ...).

Vì vậy, trong Windows 32 bit, ví dụ, trong đó mỗi quy trình có không gian địa chỉ người dùng là 2GB, cung cấp cho mỗi luồng có kích thước ngăn xếp 128K, bạn sẽ mong đợi tối đa tuyệt đối là 16384 luồng (= 2 * 1024 * 1024/128). Trong thực tế, tôi thấy tôi có thể bắt đầu khoảng 13.000 dưới XP.

Sau đó, tôi nghĩ rằng về cơ bản, bạn có thể quản lý việc tung hứng nhiều luồng trong mã của mình và không thực hiện những điều ngớ ngẩn rõ ràng (chẳng hạn như làm cho tất cả chúng chờ đợi trên cùng một đối tượng sau đó gọi notifyAll () ...), và (b) liệu hệ điều hành có thể. Về nguyên tắc, câu trả lời cho (b) là "có" nếu câu trả lời cho (a) cũng là "có".

Ngẫu nhiên, bạn có thể chỉ định kích thước ngăn xếp trong hàm tạo của Thread ; bạn không cần (và có lẽ không nên) lộn xộn với các tham số VM cho việc này.


1
Vì vậy, sử dụng hệ điều hành 64 bit. Đã bao lâu tất cả chúng ta đã sử dụng bộ xử lý 64 bit?
Tom Hawtin - tackline

Chắc chắn, tôi chỉ đưa ra một ví dụ về giới hạn lý thuyết và thực tế. Nhắc bạn, có rất nhiều máy 32 bit (bao gồm cả máy chủ) vẫn còn tồn tại ...
Neil Coffey

2

Tôi nhớ lại đã nghe một cuộc nói chuyện của Clojure khi anh ta phải chạy một trong những ứng dụng của mình trên một số máy chuyên dụng tại một triển lãm thương mại với hàng ngàn lõi (9000?), Và nó đã tải tất cả chúng. Thật không may, tôi không thể tìm thấy liên kết ngay bây giờ (trợ giúp?).

Dựa vào đó, tôi nghĩ an toàn khi nói rằng phần cứng và mã của bạn là các yếu tố giới hạn, không phải là JVM.


bạn có thể nhìn lại không? Tôi muốn thấy điều đó - nghe có vẻ thú vị và hỗ trợ rằng các ngôn ngữ chức năng dễ dàng mở rộng quy mô trên các lõi.
Thorbjørn Ravn Andersen

Bạn có thể cung cấp một liên kết đến đó? Tôi biết rằng Cliff Click, Jr., Kỹ sư trưởng của Azul Systems đã điều hành Mô phỏng Ant Colony của Rich Hickey trên hệ thống JCA lớn nhất của Azul (Azul Vega 3 Series 7300 Model 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) với 86 RAM GB và 700 con kiến ​​quản lý tối đa 700 lõi. Nhưng 9000 lõi, đó là khá ấn tượng. Đó là loại máy gì vậy?
Jörg W Mittag

Đó là mô phỏng "Kiến" mà tôi tin - đây là một liên kết nơi Rich Hickey (người tạo Clojure) nói về điều này - blip.tv/clojure/clojure-concurrency-819147 . Đó là trên một số hộp hệ thống Azul lớn với hơn 800 lõi, chủ yếu được thực hiện để chứng minh Clojure hoạt động tốt như thế nào khi xử lý đồng thời đa lõi.
mikera

@mikera lins đã hết hạn.
Thorbjørn Ravn Andersen

2

Sau khi chơi xung quanh với lớp DieLikeACode của Charlie, có vẻ như kích thước ngăn xếp luồng Java là một phần rất lớn trong số lượng luồng bạn có thể tạo.

-Xss đặt kích thước ngăn xếp luồng java

Ví dụ

java -Xss100k DieLikeADog

Nhưng, Java có giao diện Executor . Tôi sẽ sử dụng điều đó, bạn sẽ có thể gửi hàng ngàn tác vụ Runnable và để Executor xử lý các tác vụ đó với một số luồng cố định.


13
Chúng ta có thể đặt tên cho nó là DieLikeACat không? nó sẽ không chết hay còn sống cho đến khi bạn điều hành nó
Thiện chí

Cảm ơn bạn đã chỉ vào Executors, mọi người nên sử dụng nó thường xuyên hơn. Nhưng nó sẽ không hoạt động nếu Runnable/ Callablethực sự cần phải chạy liên tục, như khi nó phải xử lý giao tiếp. Nhưng nó hoàn hảo cho các truy vấn SQL.
Matthieu


0

Số lượng chủ đề tối đa phụ thuộc vào những điều sau đây:

  • Cấu hình phần cứng như vi xử lý, RAM.
  • Hệ điều hành như dù là 32 bit hay 64 bit
  • Mã bên trong phương thức chạy. Nếu mã bên trong phương thức chạy là rất lớn thì đối tượng luồng đơn sẽ có nhiều yêu cầu bộ nhớ hơn

  • 0

    Thông tin bổ sung cho các hệ thống linux (systemd) hiện đại.

    Có nhiều tài nguyên về giá trị này có thể cần điều chỉnh (chẳng hạn như Cách tăng số lượng luồng JVM tối đa (Linux 64 bit) ); tuy nhiên, một giới hạn mới được áp đặt theo cách giới hạn "T taskMax" của systemd, thiết lập pids.max trên cgroup.

    Đối với phiên đăng nhập của UserTasksMax mặc định là 33% pids_max hạn hạt nhân (thường là 12.288) và có thể được ghi đè trong /etc/systemd/logind.conf.

    Đối với các dịch vụ, DefaultT taskMax mặc định là 15% giới hạn kernel pids_max (thường là 4.915). Bạn có thể ghi đè lên dịch vụ bằng cách đặt T taskMax trong "chỉnh sửa systemctl" hoặc cập nhật DefaultT taskMax trong /etc/systemd/system.conf


    0

    Năm 2017 ... Lớp DieLikeADog.

    Chủ đề mới # 92459 Ngoại lệ trong chủ đề "chính" java.lang.OutOfMemoryError: không thể tạo chủ đề gốc mới

    i7-7700 ram 16gb


    Câu trả lời khác nhau sẽ khác nhau. Tôi nhận được 10278 với 6 GB ram.
    jamie

    -4

    Bạn có thể xử lý bất kỳ số lượng chủ đề; không có giới hạn. Tôi đã chạy đoạn mã sau trong khi xem phim và sử dụng NetBeans, và nó hoạt động bình thường / không bị tạm dừng máy. Tôi nghĩ rằng bạn có thể giữ nhiều chủ đề hơn chương trình này.

    class A extends Thread {
        public void run() {
            System.out.println("**************started***************");
            for(double i = 0.0; i < 500000000000000000.0; i++) {
                System.gc();
                System.out.println(Thread.currentThread().getName());
            }
            System.out.println("************************finished********************************");
        }
    }
    
    public class Manager {
        public static void main(String[] args) {
            for(double j = 0.0; j < 50000000000.0; j++) {
                A a = new A();
                a.start();
            }
        }
    }

    7
    Tôi biết đây là nhận xét rất muộn nhưng tôi tin rằng lý do bạn có thể bắt đầu và chạy nhiều luồng này là vì (giả sử cấu hình hệ thống bình thường và hợp lý) mỗi luồng về cơ bản in ra một dòng ra và sau đó không còn lý do nào nữa tồn tại và bị giết ngay sau đó, do đó đảm bảo nguồn tài nguyên có sẵn liên tục.
    ucsunil

    @ucsunil Điều đó không đúng. Tôi nghĩ rằng bạn đã đọc sai mã. Tôi vừa thử nó và các chủ đề khác nhau đang in ra không chỉ dòng đầu tiên, mà cả tên của chúng nữa. Có nghĩa là họ đang hoạt động. Nếu bạn nghĩ rằng bộ sưu tập rác sẽ tái chế các luồng không được ước tính, thì không, xem tại đây .
    Evgeni Sergeev

    1
    Tuy nhiên, chỉ sau một thời gian ngắn, mainsẽ ném OutOfMemoryErrorvào máy của tôi, nói rằng nó không thể tạo thêm bất kỳ chủ đề nào. Có lẽ @AnilPal, bạn đã không nhận thấy điều đó. Tôi đề nghị bao gồm một câu lệnh in khác trong main(..)phương thức, để thấy rõ khi nào nó ngừng tạo chủ đề mới sau khi ném lỗi.
    Evgeni Sergeev

    5
    thật tuyệt vời ... một khám phá về máy Turing thực tế ... tài nguyên vô hạn.
    Josh
    Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.