มี JVM หนึ่งรายการต่อแอปพลิเคชัน Java หรือไม่


91

JVM เดียวกันกับที่ใช้โดยแอปพลิเคชัน Java ทั้งหมดที่รันอยู่หรือใช้ 'หนึ่ง JVM ต่อแอปพลิเคชัน Java' หรือไม่ (กล่าวว่าแอปพลิเคชันคือ IntelliJ IDEA เซิร์ฟเวอร์และ NetBeans เป็นต้น)

นอกจากนี้มีการเชื่อมต่อระหว่าง JVM ที่กำหนดและกระบวนการที่ใช้โดยแอปพลิเคชัน Java แต่ละตัวหรือไม่


2
นี่เป็นคำถามที่ดี :)
jamie

คำตอบ:


81

โดยทั่วไปแล้วแต่ละแอปพลิเคชันจะได้รับอินสแตนซ์ JVM ของตัวเองและกระบวนการระดับ OS ของตัวเองและแต่ละอินสแตนซ์ JVM ไม่ขึ้นต่อกัน

มีรายละเอียดการใช้งานบางอย่างเช่นการแชร์ข้อมูลคลาสโดยที่อินสแตนซ์ JVM หลายอินสแตนซ์อาจแชร์ข้อมูล / หน่วยความจำบางส่วน แต่ไม่มีผลกับแอปพลิเคชันที่ผู้ใช้มองเห็นได้ (ยกเว้นเวลาเริ่มต้นที่ปรับปรุงให้ดีขึ้น)

อย่างไรก็ตามสถานการณ์ทั่วไปคือแอ็พพลิเคชันเซิร์ฟเวอร์เดียว (หรือ "เว็บเซิร์ฟเวอร์") เช่น Glassfish หรือ Tomcat ที่ใช้งานเว็บแอปพลิเคชันหลายรายการ ในกรณีนี้เว็บแอปพลิเคชันหลายรายการสามารถแชร์ JVM ได้


22

มี JVM หนึ่งรายการต่อแอปพลิเคชัน Java ไม่ควรมีการเชื่อมต่อระหว่างกันเว้นแต่คุณจะสร้างขึ้นเช่นกับเครือข่าย หากคุณกำลังทำงานภายใน IDE โดยทั่วไปโค้ดที่คุณเขียนจะทำงานใน JVM แยกต่างหาก โดยทั่วไป IDE จะเชื่อมต่อ JVM แยกต่างหากสำหรับการดีบัก หากคุณกำลังจัดการกับเว็บแอปพลิเคชันหลายรายการพวกเขาสามารถแชร์ JVM เดียวกันได้หากนำไปใช้กับเว็บคอนเทนเนอร์เดียวกัน


12

ในทางทฤษฎีคุณสามารถเรียกใช้หลายแอปพลิเคชันใน JVM ในทางปฏิบัติพวกเขาสามารถแทรกแซงซึ่งกันและกันได้หลายวิธี ตัวอย่างเช่น :

  • JVM มีหนึ่งชุดของSystem.in/ out/ การerrเข้ารหัสเริ่มต้นหนึ่งโลแคลเริ่มต้นหนึ่งชุดคุณสมบัติของระบบและอื่น ๆ หากแอปพลิเคชันหนึ่งเปลี่ยนแปลงสิ่งเหล่านี้จะมีผลต่อแอปพลิเคชันทั้งหมด
  • แอปพลิเคชันใด ๆ ที่เรียกใช้System.exit()จะฆ่าทุกแอปพลิเคชัน
  • หากเธรดของแอปพลิเคชันหนึ่งเธรดหยุดทำงานและใช้ CPU หรือหน่วยความจำมากเกินไปก็จะส่งผลกระทบต่อแอปพลิเคชันอื่นด้วย

8

จำนวน JVM ที่รันคือจำนวนของไฟล์ปฏิบัติการที่เรียกใช้ แต่ละแอปพลิเคชันดังกล่าวจะเรียกใช้โปรแกรมปฏิบัติการจาวาของตัวเอง (java.exe / javaw.exe etx สำหรับ windows) ซึ่งหมายความว่าแต่ละแอปพลิเคชันทำงานใน JVM แยกกัน


8

คำตอบสั้น ๆ : บ่อยครั้งใช่คุณจะได้รับหนึ่งแอปพลิเคชันต่อ JVM คำตอบแบบยาว: JVM สามารถใช้ในลักษณะนั้นได้และนั่นอาจเป็นตัวเลือกที่ดีที่สุด แต่ไม่จำเป็นต้องเป็นเช่นนั้น

ทุกอย่างขึ้นอยู่กับสิ่งที่คุณคิดว่าเป็น 'แอปพลิเคชัน' IDE เป็นตัวอย่างที่ดีของแอปพลิเคชันที่นำเสนอต่อผู้ใช้ปลายทาง (เช่นเรา) เป็นเอนทิตีเดียว แต่จริงๆแล้วประกอบด้วยแอปพลิเคชันพื้นฐานหลายตัว (คอมไพเลอร์ตัวทดสอบตัวทดสอบเครื่องมือวิเคราะห์แบบคงที่ผู้บรรจุหีบห่อผู้จัดการแพ็คเกจโครงการ / เครื่องมือจัดการการพึ่งพา ฯลฯ ) ในกรณีนี้มีกลเม็ดมากมายที่ IDE ใช้เพื่อให้แน่ใจว่าผู้ใช้จะได้รับประสบการณ์แบบบูรณาการในขณะเดียวกันก็ได้รับการป้องกัน (ในระดับหนึ่ง) จากความหลากหลายของเครื่องมือพื้นฐาน เคล็ดลับอย่างหนึ่งก็คือการทำบางสิ่งใน JVM ที่แยกจากกันโดยสื่อสารผ่านไฟล์ข้อความหรือผ่านอุปกรณ์ดีบักระดับแอปพลิเคชัน

แอ็พพลิเคชันเซิร์ฟเวอร์ (Wildfly, Glassfish, Websphere, Weblogic ฯลฯ ) เป็นแอปพลิเคชันที่ raison d'etre ทำหน้าที่เป็นคอนเทนเนอร์สำหรับแอปพลิเคชันอื่น ๆ ในการทำงานในกรณีนี้จากมุมมองเดียวจะมี JVM เดียวต่อแอปพลิเคชัน (เช่นหนึ่ง JVM ใช้เพื่อเรียกใช้แอ็พพลิเคชันเซิร์ฟเวอร์ทั้งหมด) แต่จริงๆแล้วมีหลายแอปพลิเคชันที่อยู่ภายใน JVM นั้นในสิทธิของตัวเองแต่ละตัวแยกออกจากกันอย่างมีเหตุผลใน classloader ของตัวเอง (ลดความเป็นไปได้ที่จะเกิด crosstalk ในกระบวนการโดยไม่ได้ตั้งใจ)

ดังนั้นทุกอย่างขึ้นอยู่กับสิ่งที่คุณคิดว่าapplicationจะเป็นจริงๆ หากคุณกำลังพูดถึง "สิ่งที่ทำงานเมื่อมีการเรียก 'main ()' เท่านั้นแสดงว่าคุณกำลังดูแอปพลิเคชันเดียวต่อ JVM - เมื่อระบบปฏิบัติการเริ่มต้น JVM JVM จะเรียกใช้public static void main()เมธอดของคลาสเดียว

แต่เมื่อแอปพลิเคชันของคุณเริ่มซับซ้อนขึ้นขอบเขตของคุณก็จะเบลอมากขึ้น IDE เช่น Intellij หรือ Eclipse จะนำสิ่งเดียวกันกับ 'javac' มาใช้ซ้ำไม่ว่าจะเป็น JVM เดียวกันหรือต่างกันรวมถึงการทำงานที่แตกต่างกัน (เช่นการทาสีหน้าจอใหม่) และผู้ใช้เว็บแอปพลิเคชันบนแอปพลิเคชันเซิร์ฟเวอร์ (JVM ที่ใช้ร่วมกัน) อาจใช้แอปพลิเคชัน 'หลัก' เดียวกันกับที่สามารถใช้ในเครื่องผ่านทางบรรทัดคำสั่ง


5

แอปพลิเคชันใด ๆ ที่มีไลบรารีที่ใช้ร่วมกันจะแชร์สำเนาเดียวกันของไลบรารีเหล่านั้น Java มีไลบรารีที่ใช้ร่วมกันอยู่พอสมควร อย่างไรก็ตามคุณจะไม่สังเกตเห็นความแตกต่างยกเว้นหน่วยความจำบางส่วนที่บันทึกไว้


2

มาสายเล็กน้อยอย่างไรก็ตามข้อมูลนี้อาจเป็นประโยชน์สำหรับใครบางคน ในระบบ Linux หากคุณต้องการทราบจำนวน JVM ที่รันอยู่คุณสามารถลองใช้คำสั่งนี้

$ ps -ef | grep "[j]ava" | wc -l

psเพื่อแสดงรายการกระบวนการgrepเพื่อค้นหากระบวนการที่มี "java" และwcนับบรรทัดที่ส่งคืน


0

อันที่จริงนี่เป็นคำถามหนึ่งที่อาจมีคำตอบที่สับสนมาก เพื่อให้สั้นจริง:

  1. ใช่ต่อกระบวนการ java ต่อ JVM
  2. Runtime และ ProcessBuilder เป็นไปตามกฎนี้
  3. การโหลดไหโดยใช้การสะท้อนกลับจากนั้นการเรียกใช้งานหลักจะไม่เกิด JVM ใหม่
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.