เมื่อฉันสร้างวัตถุจะมีการจัดสรรหน่วยความจำใหม่ให้กับทั้งเขตข้อมูลอินสแตนซ์และวิธีการหรือเฉพาะกับเขตข้อมูลอินสแตนซ์


14

ฉันมีคลาสต่อไปนี้

class Student{

int rollNumber;
int marks;

public void setResult(int rollNumber, int marks){

    this.rollNumber=rollNumber;
    this.marks=marks;   
}

public void displayResult(){

    System.out.println("Roll Number= "+this.rollNumber+"   Marks= "+this.marks);

}
}

ตอนนี้ฉันสร้างวัตถุสองประเภทที่เป็นนักเรียนดังนี้

Student s1=new Student();
Student s2=new Student();

ตอนนี้มีการจัดสรรหน่วยความจำสองชุดที่แตกต่างกันสำหรับฟิลด์อินสแตนซ์ ตอนนี้คำถามของฉันคือการจัดสรรหน่วยความจำสำหรับวิธีการ ( setResultและdisplayResult) สองครั้งหรือหนึ่งครั้ง?

โปรดดูรูปต่อไปนี้และคุณสามารถช่วยฉันบอกว่ารูปใดให้ข้อมูลที่ถูกต้อง

ป้อนคำอธิบายรูปภาพที่นี่


1
ที่ใช้ร่วมกันวิจัยของคุณช่วยให้ทุกคน บอกเราว่าคุณได้ลองทำอะไรและทำไมมันถึงไม่ตรงกับความต้องการของคุณ สิ่งนี้แสดงให้เห็นว่าคุณใช้เวลาในการพยายามช่วยตัวเองมันช่วยให้เราไม่ต้องย้ำคำตอบที่ชัดเจนและส่วนใหญ่จะช่วยให้คุณได้คำตอบที่เฉพาะเจาะจงและเกี่ยวข้องมากขึ้น ดูวิธีถาม
gnat

3
ฉันกำลังเรียนรู้จาวา ... และในวัสดุทั้งหมดที่พวกเขาบอกว่าเมื่อใดก็ตามที่เราสร้างวัตถุหน่วยความจำที่สดใหม่จะถูกจัดสรรไปยังเขตข้อมูลอินสแตนซ์ทั้งหมด .. แต่ไม่มีวัสดุใดบอกว่าหน่วยความจำใหม่ ไม่
Harish_N

คำตอบ:


13

รหัสสำหรับวิธีการเป็นส่วนหนึ่งของClass(กระชับมากขึ้นClass<Student>) และจะถูกโหลดลงในหน่วยความจำเมื่อโหลดคลาสครั้งแรก

ที่กล่าวว่าเมื่อคุณเรียกใช้เมธอดหน่วยความจำเพิ่มเติมใด ๆ ที่ใช้ในการจัดสรรหน่วยความจำให้กับพารามิเตอร์ตัวแปรท้องถิ่นผลการแสดงออกชั่วคราวค่าตอบแทนและอื่น ๆ แต่ความทรงจำดังกล่าวจะถูกจัดสรรในสแต็ค (หน่วยความจำที่ใช้เมื่อมีการสร้างอินสแตนซ์ใหม่จะถูกจัดสรรในกอง

ตามคำถามของคุณควรมีความชัดเจนในขณะนี้ว่ารูป B ถูกต้อง (แม้ว่ามันจะไม่สะท้อนสิ่งที่เกิดขึ้นเมื่อคุณเรียกวิธีการจริง)


ตกลง. ฉันชัดเจนแล้ว 90% ในตอนนี้ .... แต่มีข้อสงสัยเล็กน้อย .. สมมติว่าฉันสร้างนักเรียน 10 ประเภทจากนั้นมีหน่วยความจำใหม่เพียง 1 ชุดเท่านั้นที่จัดสรรให้กับวิธีการที่มีอยู่ในชั้นเรียนของนักเรียน จัดสรรเพื่อจัดเก็บตัวแปรอินสแตนซ์สำหรับ 10 วัตถุ .. ฉันถูกไหม
Harish_N

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

อีกสิ่งหนึ่ง ... ฉันถามคำถามที่ทำให้จาวาอยู่ในใจ .... สิ่งเดียวกันนี้เกิดขึ้นในจาวา .....
Harish_N

ข้อกำหนดภาษา Java ไม่ได้พูดอะไรเกี่ยวกับจำนวนหน่วยความจำที่จัดสรรเมื่อใดและเพื่อวัตถุประสงค์อะไร นั่นคือสิ่งที่เหลือให้กับผู้ดำเนินการและผู้ดำเนินการทุกคนอาจเลือกแตกต่าง
Jörg W Mittag

6

ฟิลด์อินสแตนซ์ (รวมถึงฟิลด์การสำรองคุณสมบัติ) รับสำเนา N สำหรับวัตถุ N

ฟิลด์แบบสแตติกได้รับสำเนาเดียวต่อคลาส

เมธอดคือบล็อกของ bytecode (หรือหลังจาก JIT บล็อกของคำสั่งพื้นฐาน) ซึ่งเป็นส่วนหนึ่งของโปรแกรม "อิมเมจ" หรือเซ็กเมนต์โค้ดที่ทำงานได้ วิธีการเป็นส่วนหนึ่งของอิมเมจโปรแกรมแล้วขณะที่มันอยู่บนดิสก์ เมื่อโหลดอิมเมจโดย OS (หรือ CLR) แล้วจะมีสำเนาวิธีใช้ร่วมกันหนึ่งชุด

พวกเขาไม่ได้เป็นส่วนหนึ่งของ "ฮีป" หรือการจัดสรรรันไทม์โดยทั่วไปยกเว้นในกรณีที่คุณอาจใช้คอมไพเลอร์โฮสต์ได้เพื่อรวบรวมวิธีการใหม่ได้ทันที วิธีการไม่ได้รับ "การปันส่วน" เช่นเดียวกับวัตถุและพวกมันไม่ใช่ "การจัดสรร" ที่สัมพันธ์กับการสร้างวัตถุ พวกมันมีอยู่เป็นส่วนหนึ่งของโปรแกรมก่อนที่วัตถุหนึ่งชิ้นจะถูกสร้างขึ้นทันที แม้แต่แกะ / ผู้ได้รับมอบหมายก็ไม่ได้ถูกจัดสรรในทันที คอมไพเลอร์สร้างคลาสตามความต้องการเพื่อใช้ออบเจ็กต์รหัสไดนามิกอื่น ๆ เหล่านี้และพวกมันยังมีอยู่เป็นส่วนหนึ่งของอิมเมจไบต์บนดิสก์

อัปเดตต่อความคิดเห็น:

มาตรฐาน JVM มีสิ่งนี้เพื่อพูดว่า:

2.5.4 พื้นที่วิธีการ

Java Virtual Machine มีพื้นที่เมธอดที่แบ่งใช้ระหว่างเธรด Java Virtual Machine ทั้งหมด พื้นที่เมธอดนั้นคล้ายคลึงกับพื้นที่เก็บข้อมูลสำหรับโค้ดที่คอมไพล์ของภาษาทั่วไปหรือคล้ายคลึงกับเซ็กเมนต์ "ข้อความ" ในกระบวนการของระบบปฏิบัติการ มันเก็บโครงสร้างต่อคลาสเช่นสระว่ายน้ำคงที่เวลาทำงานข้อมูลและวิธีการและรหัสสำหรับวิธีการและการก่อสร้างรวมถึงวิธีการพิเศษ (§2.9) ที่ใช้ในการเริ่มต้นเรียนและอินสแตนซ์และการเริ่มต้นอินเทอร์เฟซ

พื้นที่เมธอดถูกสร้างบนการเริ่มต้นเครื่องเสมือน แม้ว่าพื้นที่เมธอดนั้นเป็นส่วนหนึ่งของฮีปอย่างมีเหตุผลการใช้งานแบบง่ายอาจเลือกที่จะไม่เก็บขยะหรือทำให้กะทัดรัด ข้อกำหนดคุณลักษณะ Java Virtual Machine เวอร์ชันนี้ไม่ได้กำหนดตำแหน่งของพื้นที่เมธอดหรือนโยบายที่ใช้เพื่อจัดการโค้ดที่คอมไพล์ พื้นที่วิธีการอาจมีขนาดคงที่หรืออาจขยายได้ตามที่กำหนดโดยการคำนวณและอาจมีการทำสัญญาหากพื้นที่วิธีที่มีขนาดใหญ่กว่าไม่จำเป็น หน่วยความจำสำหรับพื้นที่เมธอดไม่จำเป็นต้องต่อเนื่องกัน

ดังนั้นจึงเป็นที่ชัดเจนว่า (1) ใช่สเป็คไม่ได้บอกว่าจะทำอย่างไร แต่ (2) มีความคล้ายคลึงกับพื้นที่จัดเก็บสำหรับโค้ดที่คอมไพล์ของภาษาดั้งเดิมเช่น ส่วนข้อความ นี่คือจุดที่ฉันทำ


สิ่งที่คุณพูดนั้นสมเหตุสมผล แต่รับรองโดย JLS จริงหรือ? โดยปกติแล้ว JLS ให้ผู้ใช้งานมีปัญหามากมายเช่นนี้
Jörg W Mittag

ไม่แน่ใจในจุดนั้น @ JörgWMittag คุณอาจจะถูก จุดที่ฉันพยายามทำคือ "new T ()" ไม่ได้จัดสรรอินสแตนซ์ใหม่ของวิธีการ สำหรับข้อมูลเฉพาะของ JVM นั้นตัวโหลดคลาสจะจัดเก็บ bytecode ในฮีปและฉันเดาว่ามีสถานการณ์ที่เป็นไปได้ที่คลาสตัวเองจะถูกสร้างอินสแตนซ์และแม้แต่เก็บขยะ แต่มันคือรายละเอียดการนำไปใช้ของรันไทม์และแนวคิดรวบยอดฮีปที่ฉันพูดถึงคือฮีป "ผู้ใช้" คลาส & เมธอดไม่ถือเป็นข้อมูลในบริบทผู้ใช้ปกติ แต่เนื่องจากเราสามารถควบคุม classloader จาก userland ได้ฉันเดาว่าไม่รู้
codenheim

JLS ไม่ได้พูดถึงกองเลยใช่มั้ย มันถูกกฎหมายอย่างสมบูรณ์ในการใช้งานจาวาด้วยสแต็กแบบไดนามิกและไม่มีฮีปแทนสแต็กขนาดคงที่ที่ จำกัด และฮีปแบบไดนามิก JLS ยังไม่ได้พูดอะไรเกี่ยวกับ JVM มันสามารถใช้งาน Java ได้อย่างสมบูรณ์แบบหากไม่มี JVM
Jörg W Mittag

คุณกำลังอ้างอิง JLS แต่ฉันกำลังพูดถึง JVM มาตรฐาน JVM กล่าวถึงกองแน่นอน คุณต้องระบุขอบเขต / อายุการใช้งานตัวแปรที่หนีขอบเขตภายในของสแต็ก สำหรับสิ่งที่เป็นไปได้ในทางทฤษฎีฉันชอบคิดในแง่ของ "การใช้งานที่รู้จัก" ฉันค่อนข้างมั่นใจว่าการใช้ JVM แบบเต็มโดยไม่ต้องใช้ heap primitive นั้นเป็นงานที่ยากหรือเป็นไปไม่ได้เนื่องจาก JVM ไม่ใช่เครื่องกองซ้อนที่บริสุทธิ์ ความเข้าใจของฉันเกี่ยวกับเครื่องจักร Forth และสถาปัตยกรรมกองซ้อนที่บริสุทธิ์อื่น ๆ นั้นอาจเป็นไปได้ถ้ามีดั้งเดิมสำหรับการเข้าถึงตัวแปรแบบสุ่ม แต่ฉันไม่เห็นเลย
codenheim

@ JörgWMittag - ฉันได้เพิ่มคำตอบบางอย่างที่อาจเป็นที่สนใจสำหรับการสนทนาของเรา ประเด็นคือฉันกำลังวาดความคล้ายคลึงกับรหัสดั้งเดิมหรือส่วนข้อความในระบบรันไทม์ทั่วไป
codenheim

-4

วัตถุที่จัดสรรในหน่วยความจำฮีปเมื่อวัตถุถูกจัดสรรสล็อตสำหรับตัวแปรอินสแตนซ์ทั้งหมดจะถูกสร้างและทำลายเมื่อวัตถุถูกทำลายดังนั้นตัวแปรอินสแตนซ์จะถูกจัดสรรในหน่วยความจำฮีปด้วยเช่นกันและจะสร้างตัวแปรท้องถิ่นในสแต็ค วิธีการที่เรียกว่า


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