ประการแรกตามที่ควรชัดเจนสำหรับคุณในขณะนี้มีน้อยคนที่สามารถยืนยันคำตอบเหล่านี้จากความรู้โดยตรง มีเพียงไม่กี่คนที่ทำงานกับ JVM ของ HotSpot ล่าสุดหรือศึกษาพวกเขาในเชิงลึกที่จำเป็นต้องรู้จริงๆ คนส่วนใหญ่ที่นี่ (รวมถึงตัวฉันเองด้วย) กำลังตอบโดยอิงจากสิ่งที่พวกเขาเห็นเขียนไว้ที่อื่นหรือสิ่งที่พวกเขาสรุปได้ โดยปกติสิ่งที่เขียนไว้ที่นี่หรือในบทความและหน้าเว็บต่างๆจะขึ้นอยู่กับแหล่งข้อมูลอื่นซึ่งอาจสรุปได้หรือไม่ก็ได้ บ่อยครั้งที่มันง่ายขึ้นไม่ถูกต้องหรือผิดธรรมดา
หากคุณต้องการการยืนยันคำตอบที่ชัดเจนคุณต้องดาวน์โหลดซอร์สโค้ด OpenJDK ... และทำการค้นคว้าของคุณเองโดยการอ่านและทำความเข้าใจซอร์สโค้ด การถามคำถามเกี่ยวกับ SO หรือการอ่านบทความบนเว็บแบบสุ่มไม่ใช่เทคนิคการวิจัยทางวิชาการที่ดี
ต้องบอกว่า ...
... คำถามของฉันคือซันโดยเฉพาะ
ในขณะที่มีการถามคำถามนี้ Sun Microsystems ก็หยุดอยู่ ดังนั้นคำถามจึงเจาะจง Oracle AFAIK การใช้งาน JVM ของบุคคลที่สามในปัจจุบัน (ไม่ใช่การวิจัย) ทั้งหมดเป็นพอร์ตโดยตรงของรีลีส OpenJDK หรือสืบเชื้อสายมาจากรุ่นอื่นของ Sun / Oracle
คำตอบด้านล่างนี้ใช้กับ Oracle Hotspot และ OpenJDK และอาจใช้กับรุ่นอื่น ๆ ส่วนใหญ่เช่นกัน ... รวมถึง GraalVM
1) คลาส (โหลดโดย classloaders) ไปในพื้นที่พิเศษบนฮีป: การสร้างแบบถาวร
ก่อนหน้า Java 8 ใช่
ตั้งแต่ Java 8 พื้นที่ PermGen ถูกแทนที่ด้วย Metaspace คลาสที่โหลดและคอมไพล์ JIT ไปที่นั่นแล้ว PermGen ไม่มีแล้ว
2) ข้อมูลทั้งหมดที่เกี่ยวข้องกับคลาสเช่นชื่อคลาสอาร์เรย์อ็อบเจ็กต์ที่เกี่ยวข้องกับคลาสอ็อบเจ็กต์ภายในที่ JVM ใช้ (เช่น java / lang / Object) และข้อมูลการปรับให้เหมาะสมจะเข้าสู่พื้นที่การสร้างแบบถาวร
มากหรือน้อยใช่ ฉันไม่แน่ใจว่าคุณหมายถึงอะไรจากสิ่งเหล่านั้น ฉันคาดเดาว่า "ออบเจ็กต์ภายในที่ใช้โดย JVM (เช่น java / lang / Object)" หมายถึงตัวบอกคลาส JVM ภายใน
3) ตัวแปรสมาชิกคงที่ทั้งหมดจะถูกเก็บไว้ในพื้นที่การสร้างแบบถาวรอีกครั้ง
ตัวแปรเองใช่ ตัวแปรเหล่านี้ (เช่นเดียวกับตัวแปร Java ทั้งหมด) จะเก็บค่าดั้งเดิมหรือการอ้างอิงอ็อบเจ็กต์ อย่างไรก็ตามในขณะที่ตัวแปรสมาชิกแบบสแตติกอยู่ในเฟรมที่จัดสรรในฮีป permgen อ็อบเจ็กต์ / อาร์เรย์ที่อ้างถึงโดยตัวแปรเหล่านั้นอาจได้รับการจัดสรรในฮีปใด ๆ
4) วัตถุไปกองที่แตกต่างกัน: คนรุ่นใหม่
ไม่จำเป็น. วัตถุขนาดใหญ่อาจถูกจัดสรรให้กับรุ่นที่ครอบครองโดยตรง
5) มีเพียงหนึ่งสำเนาของแต่ละวิธีต่อคลาสคือวิธีคงที่หรือไม่คงที่ สำเนานั้นใส่ไว้ในพื้นที่การสร้างแบบถาวร
สมมติว่าคุณอ้างถึงรหัสของวิธีการแล้ว AFAIK ใช่ มันอาจจะซับซ้อนกว่าเล็กน้อย ตัวอย่างเช่นรหัสอาจมีอยู่ในรูปแบบ bytecode และ / หรือเนทีฟโค้ดในช่วงเวลาที่ต่างกันในช่วงชีวิตของ JVM
... สำหรับวิธีการที่ไม่คงที่พารามิเตอร์และตัวแปรโลคัลทั้งหมดจะเข้าสู่สแต็ก - และเมื่อใดก็ตามที่มีการเรียกใช้เมธอดนั้นอย่างเป็นรูปธรรมเราจะได้สแต็กเฟรมใหม่ที่เชื่อมโยงกับมัน
ใช่.
... ฉันไม่แน่ใจว่าตัวแปรโลคัลของวิธีคงที่ถูกเก็บไว้ที่ไหน พวกเขาอยู่ในกองของการสร้างแบบถาวรหรือไม่? หรือเพียงข้อมูลอ้างอิงถูกเก็บไว้ในพื้นที่การสร้างแบบถาวรและสำเนาจริงอยู่ที่อื่น (ที่ไหน?)
ไม่ได้มีการจัดเก็บไว้ในสแต็กเช่นเดียวกับตัวแปรโลคัลในวิธีการไม่คงที่
6) ฉันไม่แน่ใจด้วยว่าประเภทการส่งคืนของวิธีการเก็บไว้ที่ไหน
หากคุณหมายถึงค่าที่ส่งคืนโดยการเรียกใช้เมธอด (ไม่ใช่โมฆะ) ค่านั้นจะถูกส่งกลับบนสแต็กหรือในทะเบียนเครื่อง หากส่งคืนบนสแต็กจะใช้เวลา 1 หรือสองคำขึ้นอยู่กับประเภทการส่งคืน
7) หากออบเจ็กต์ (ในคนรุ่นใหม่) ต้องการใช้สมาชิกแบบคงที่ (ในรุ่นถาวร) พวกเขาจะได้รับการอ้างอิงถึงสมาชิกคงที่ && พวกเขาจะได้รับพื้นที่หน่วยความจำเพียงพอที่จะจัดเก็บประเภทการส่งคืนของวิธีการ ฯลฯ .
นั่นไม่ถูกต้อง (หรืออย่างน้อยคุณก็ไม่ได้แสดงออกอย่างชัดเจน)
หากวิธีการบางอย่างเข้าถึงตัวแปรสมาชิกคงสิ่งที่จะได้รับเป็นทั้งค่าดั้งเดิมหรือวัตถุอ้างอิง สิ่งนี้อาจถูกกำหนดให้กับตัวแปรหรือพารามิเตอร์โลคัล (ที่มีอยู่) ซึ่งกำหนดให้กับสมาชิกแบบคงที่หรือไม่คงที่ (ที่มีอยู่) กำหนดให้กับองค์ประกอบ (ที่มีอยู่) ของอาร์เรย์ที่จัดสรรไว้ก่อนหน้านี้หรือเพียงแค่ใช้และทิ้งไป
ไม่ว่าในกรณีใดที่จำเป็นต้องจัดสรรหน่วยเก็บข้อมูลใหม่เพื่อเก็บค่าอ้างอิงหรือค่าดั้งเดิม
โดยปกติแล้วหน่วยความจำหนึ่งคำคือสิ่งที่จำเป็นในการจัดเก็บอ็อบเจ็กต์หรือการอ้างอิงอาร์เรย์และโดยทั่วไปแล้วค่าดั้งเดิมจะใช้คำหนึ่งหรือสองคำขึ้นอยู่กับสถาปัตยกรรมฮาร์ดแวร์
ไม่ว่าในกรณีใดผู้เรียกจะต้องจัดสรรพื้นที่เพื่อเก็บอ็อบเจ็กต์ / อาร์เรย์ที่ส่งคืนโดยวิธีการ ใน Java อ็อบเจ็กต์และอาร์เรย์จะถูกส่งกลับโดยใช้ความหมาย pass-by-value เสมอ ... แต่ค่าที่ส่งกลับเป็นการอ้างอิงอ็อบเจ็กต์หรืออาร์เรย์
สำหรับข้อมูลเพิ่มเติมโปรดดูแหล่งข้อมูลเหล่านี้: