Java VM สามารถรองรับเธรดได้กี่เธรด สิ่งนี้แตกต่างกันไปตามผู้ขายหรือไม่ โดยระบบปฏิบัติการ? ปัจจัยอื่น ๆ ?
Java VM สามารถรองรับเธรดได้กี่เธรด สิ่งนี้แตกต่างกันไปตามผู้ขายหรือไม่ โดยระบบปฏิบัติการ? ปัจจัยอื่น ๆ ?
คำตอบ:
ขึ้นอยู่กับซีพียูที่คุณใช้บนระบบปฏิบัติการกระบวนการอื่นกำลังทำอะไรจาวาปล่อยสิ่งที่คุณใช้และปัจจัยอื่น ๆ ฉันเคยเห็นเซิร์ฟเวอร์ Windows มี> 6500 เธรดก่อนนำเครื่องลงมา แน่นอนว่าเธรดส่วนใหญ่ไม่ได้ทำอะไรเลย เมื่อเครื่องมีจำนวนประมาณ 6500 เธรด (ใน Java) เครื่องทั้งหมดก็เริ่มมีปัญหาและไม่เสถียร
ประสบการณ์ของฉันแสดงให้เห็นว่า Java (เวอร์ชันล่าสุด) สามารถใช้เธรดได้อย่างมีความสุขเท่าที่คอมพิวเตอร์สามารถโฮสต์ได้โดยไม่มีปัญหา
แน่นอนคุณต้องมี RAM เพียงพอและคุณต้องเริ่มต้น Java ด้วยหน่วยความจำเพียงพอที่จะทำทุกอย่างที่เธรดกำลังทำอยู่และมีสแต็กสำหรับแต่ละเธรด เครื่องใด ๆ ที่มี CPU ที่ทันสมัย (รุ่นล่าสุดของ AMD หรือ Intel) และหน่วยความจำ 1-2 กิกะไบต์ (ขึ้นอยู่กับระบบปฏิบัติการ) สามารถรองรับ JVM ด้วยเธรดนับพัน
หากคุณต้องการคำตอบที่เฉพาะเจาะจงมากกว่านี้ทางออกที่ดีที่สุดของคุณคือทำโปรไฟล์
อืม
มีพารามิเตอร์หลายอย่างที่นี่ VM ที่เฉพาะเจาะจงรวมถึงมักจะมีพารามิเตอร์เวลาทำงานบน VM เช่นกัน มันค่อนข้างขับเคลื่อนด้วยระบบปฏิบัติการ: ระบบปฏิบัติการที่รองรับรองรับเธรดและมีข้อ จำกัด อะไรบ้าง หาก VM ใช้เธรดระดับ OS จริง ๆ สิ่งที่ดีคือเธรดเธรดเก่า / สีเขียว
"สนับสนุน" หมายถึงคำถามอื่น หากคุณเขียนโปรแกรม Java ที่มีลักษณะเหมือน
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(และอย่าบ่นเกี่ยวกับรายละเอียดเล็ก ๆ น้อย ๆ เกี่ยวกับไวยากรณ์ฉันอยู่ในกาแฟถ้วยแรก) จากนั้นคุณควรคาดหวังว่าจะได้รับกระทู้นับร้อยหรือหลายพันรายการ แต่การสร้างเธรดนั้นมีราคาค่อนข้างแพง ไม่ชัดเจนว่าคุณสามารถให้เธรดเหล่านั้นทำอะไรที่มีประโยชน์ได้
โอเคไม่สามารถต้านทานได้ นี่คือโปรแกรมทดสอบเล็ก ๆ ของฉันพร้อมการปรุงแต่งสองครั้ง:
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();
}
}
}
บน OS / X 10.5.6 บน Intel และ Java 6 5 (ดูความคิดเห็น) นี่คือสิ่งที่ฉันได้รับ
กระทู้ใหม่ # 2547 กระทู้ใหม่ # 2548 กระทู้ใหม่ # 2549 ไม่สามารถสร้างเธรด: 5 กระทู้ใหม่ # 2550 ข้อยกเว้นในเธรด "main" java.lang.OutOfMemoryError: ไม่สามารถสร้างเธรดดั้งเดิมใหม่ ที่ java.lang.Thread.start0 (วิธีเนทีฟ) ที่ java.lang.Thread.start (Thread.java,592) ที่ DieLikeADog.main (DieLikeADog.java:6)
หลังจากอ่านโพสต์ของ Charlie Martin ฉันอยากรู้ว่าขนาดฮีปสร้างความแตกต่างในจำนวนเธรดที่คุณสามารถสร้างได้หรือไม่และฉันก็รู้สึกตะลึงกับผลลัพธ์
ใช้ JDK 1.6.0_11 บน Vista Home Premium SP1 ฉันใช้งานแอปพลิเคชันทดสอบของ Charlie ที่มีขนาดฮีปต่างกันระหว่าง 2 MB ถึง 1024 MB
ตัวอย่างเช่นในการสร้างฮีป 2 MB ฉันจะเรียกใช้ JVM ด้วยอาร์กิวเมนต์ -Xms2m -Xmx2m
นี่คือผลลัพธ์ของฉัน:
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
ดังนั้นขนาดฮีปจึงมีความสำคัญอย่างแน่นอน แต่ความสัมพันธ์ระหว่างขนาดฮีปกับจำนวนเธรดสูงสุดนับเป็นสัดส่วนแบบไม่ต่อเนื่อง
ซึ่งแปลก
ฉันรู้ว่าคำถามนี้ค่อนข้างเก่า แต่ต้องการแบ่งปันสิ่งที่ค้นพบของฉัน
แล็ปท็อปของฉันสามารถจัดการโปรแกรมที่วาง25,000
เธรดและเธรดเหล่านั้นทั้งหมดเขียนข้อมูลบางอย่างในฐานข้อมูล MySql ในช่วงเวลาปกติ 2 วินาที
ฉันวิ่งโปรแกรมนี้ด้วย10,000 threads
สำหรับ30 minutes continuously
แล้วยังระบบของฉันมีเสถียรภาพและฉันก็สามารถที่จะทำดำเนินการอื่น ๆ ตามปกติเช่นการเรียกดูเปิดปิดโปรแกรมอื่น ๆ ฯลฯ
ด้วย25,000 threads
ระบบslows down
แต่ก็ยังตอบสนองได้
ด้วย50,000 threads
ระบบstopped responding
ทันทีและฉันต้องรีสตาร์ทระบบด้วยตนเอง
รายละเอียดระบบของฉันมีดังนี้:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
-Xmx2048m
ก่อนที่จะใช้ผมตั้งอาร์กิวเมนต์ JVM
หวังว่ามันจะช่วย
สูงสุดทางทฤษฎีที่แน่นอนโดยทั่วไปกระบวนการของพื้นที่ที่อยู่ของผู้ใช้แบ่งออกตามขนาดด้ายสแต็ค (แม้ว่าในความเป็นจริงหากทุกหน่วยความจำของคุณจะถูกสงวนไว้สำหรับกองด้ายคุณจะไม่ได้มีโปรแกรมการทำงาน ... )
ตัวอย่างเช่นภายใต้ Windows แบบ 32 บิตที่แต่ละกระบวนการมีพื้นที่ที่อยู่ผู้ใช้ 2GB ทำให้แต่ละเธรดมีขนาดสแต็กขนาด 128K แต่ละเธรดคุณคาดหวังจำนวนสูงสุด 16384 เธรด (= 2 * 1024 * 1024/128) ในทางปฏิบัติฉันพบว่าฉันสามารถเริ่มต้นประมาณ 13,000 ภายใต้ XP
จากนั้นฉันคิดว่าคุณจำเป็นต้องรู้หรือไม่ว่า (a) คุณสามารถจัดการการเล่นกลที่หลายเธรดในรหัสของคุณและไม่ทำสิ่งที่โง่เขลาอย่างเห็นได้ชัด (เช่นทำให้พวกเขาทั้งหมดรอวัตถุเดียวกันแล้วโทรแจ้งAllAll) และ (b) ระบบปฏิบัติการสามารถทำได้หรือไม่ โดยหลักการแล้วคำตอบสำหรับ (b) คือ "ใช่" ถ้าคำตอบของ (a) ก็คือ "ใช่" เช่นกัน
อนึ่งคุณสามารถระบุขนาดสแต็คในตัวสร้างของด้าย ; คุณไม่จำเป็นต้อง (และอาจไม่ควร) ยุ่งเกี่ยวกับพารามิเตอร์ VM สำหรับสิ่งนี้
ฉันจำได้ว่าได้ยินการพูดคุยของ Clojure ว่าเขาต้องใช้แอพใดแอพหนึ่งของเขาบนเครื่องพิเศษบางอย่างในงานแสดงสินค้าที่มีคอร์นับพัน (9000?) และมันโหลดมันทั้งหมด ขออภัยฉันไม่สามารถหาลิงก์ได้ในขณะนี้ (ช่วยด้วย)
ตามที่ฉันคิดว่ามันปลอดภัยที่จะบอกว่าฮาร์ดแวร์และรหัสของคุณเป็นปัจจัย จำกัด ไม่ใช่ JVM
หลังจากเล่นกับคลาส DieLikeACode ของ Charlie ดูเหมือนว่าขนาดของเธรด Java จะเป็นส่วนใหญ่ของจำนวนเธรดที่คุณสามารถสร้างได้
-Xss ตั้งค่าขนาดสแต็กของเธรด Java
ตัวอย่างเช่น
java -Xss100k DieLikeADog
แต่ Java มีส่วนติดต่อผู้บริหาร ฉันจะใช้สิ่งนั้นคุณจะสามารถส่งงาน Runnable หลายพันงานและให้ Executor ประมวลผลงานเหล่านั้นด้วยจำนวนเธรดที่แน่นอน
Runnable
/ Callable
ต้องการทำงานอย่างต่อเนื่องเช่นเมื่อต้องจัดการกับการสื่อสาร แต่มันเหมาะสำหรับการสืบค้น SQL
อย่างน้อยบน Mac OS X 10.6 32 บิตมีข้อ จำกัด (2560) จากระบบปฏิบัติการ ตรวจสอบเธรด stackoverflowนี้
จำนวนเธรดสูงสุดขึ้นอยู่กับสิ่งต่อไปนี้:
ข้อมูลเพิ่มเติมสำหรับระบบ linux ที่ทันสมัย (systemd)
มีทรัพยากรมากมายเกี่ยวกับค่านี้ที่อาจต้องมีการปรับแต่ง (เช่นวิธีเพิ่มจำนวนสูงสุดของเธรด JVM (Linux 64 บิต) ); อย่างไรก็ตามมีการกำหนดขีด จำกัด ใหม่ด้วยวิธี จำกัด systemd "TasksMax" ซึ่งตั้งค่า pids.max บน cgroup
สำหรับเซสชันล็อกอินค่าดีฟอลต์ของUserTasksMaxคือ 33% ของขีด จำกัด เคอร์เนล pids_max (ปกติคือ 12,288) และสามารถแทนที่ได้ใน /etc/systemd/logind.conf
สำหรับบริการDefaultTasksMaxค่าเริ่มต้นคือ 15% ของจำนวนเคอร์เนลที่ จำกัด pids_max (ปกติ 4,915) คุณสามารถแทนที่สำหรับบริการโดยการตั้งค่า TasksMax ใน "systemctl แก้ไข" หรืออัปเดต DefaultTasksMax ใน /etc/systemd/system.conf
ปี 2017 ... ชั้นเรียน DieLikeADog
ใหม่เธรด # 92459 ข้อยกเว้นในเธรด "main" java.lang.OutOfMemoryError: ไม่สามารถสร้างเธรดดั้งเดิมใหม่
i7-7700 16gb ram
คุณสามารถประมวลผลเธรดจำนวนเท่าใดก็ได้ ไม่มีขีด จำกัด ฉันเรียกใช้รหัสต่อไปนี้ในขณะที่ดูภาพยนตร์และใช้ NetBeans และทำงานได้อย่างถูกต้อง / ไม่ต้องหยุดเครื่อง ฉันคิดว่าคุณสามารถเก็บกระทู้ได้มากกว่าที่โปรแกรมนี้ทำ
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();
}
}
}
main
ก็จะโยนลงOutOfMemoryError
บนเครื่องของฉันโดยบอกว่ามันไม่สามารถสร้างเธรดได้อีก บางที @AilPal คุณไม่สังเกตเห็นว่า ฉันขอแนะนำให้รวมคำสั่งการพิมพ์อื่นในmain(..)
วิธีการเพื่อให้เห็นอย่างชัดเจนเมื่อสิ้นสุดการสร้างเธรดใหม่หลังจากทิ้งข้อผิดพลาด