1. บทนำ
ในการเรียกใช้แอปพลิเคชันด้วยวิธีที่เหมาะสมที่สุด JVM จะแบ่งหน่วยความจำออกเป็นหน่วยความจำแบบสแต็กและฮีป เมื่อใดก็ตามที่เราประกาศตัวแปรและออบเจ็กต์ใหม่ให้เรียกใช้เมธอดใหม่ประกาศStringหรือดำเนินการที่คล้ายกัน JVM จะกำหนดหน่วยความจำให้กับการดำเนินการเหล่านี้จาก Stack Memory หรือ Heap Space
ในบทช่วยสอนนี้เราจะพูดถึงโมเดลหน่วยความจำเหล่านี้ เราจะขอความแตกต่างที่สำคัญบางประการระหว่างสิ่งเหล่านี้วิธีจัดเก็บใน RAM คุณสมบัติที่นำเสนอและสถานที่ที่จะใช้
2. Stack Memory ใน Java
Stack Memory ใน Java ใช้สำหรับการจัดสรรหน่วยความจำแบบคงที่และการดำเนินการของเธรด ประกอบด้วยค่าดั้งเดิมที่เฉพาะเจาะจงสำหรับวิธีการและการอ้างอิงถึงอ็อบเจ็กต์ที่อยู่ในฮีปซึ่งอ้างถึงจากเมธอด
การเข้าถึงหน่วยความจำนี้อยู่ในลำดับ Last-In-First-Out (LIFO) เมื่อใดก็ตามที่มีการเรียกใช้เมธอดใหม่บล็อกใหม่ที่ด้านบนของสแต็กจะถูกสร้างขึ้นซึ่งมีค่าเฉพาะสำหรับเมธอดนั้นเช่นตัวแปรดั้งเดิมและการอ้างอิงถึงอ็อบเจ็กต์
เมื่อเมธอดเสร็จสิ้นการดำเนินการเฟรมสแต็กที่เกี่ยวข้องจะถูกล้างโฟลว์จะกลับไปที่เมธอดการโทรและช่องว่างจะพร้อมใช้งานสำหรับวิธีถัดไป
2.1. คุณสมบัติที่สำคัญของหน่วยความจำแบบกองซ้อน
นอกเหนือจากสิ่งที่เราได้พูดถึงไปแล้วคุณสมบัติอื่น ๆ ของหน่วยความจำสแต็กมีดังต่อไปนี้:
- มันจะเติบโตและหดตัวเมื่อมีการเรียกวิธีการใหม่และส่งคืนตามลำดับ
- ตัวแปรภายในสแต็กจะมีอยู่ตราบเท่าที่เมธอดที่สร้างขึ้นนั้นทำงานอยู่
- จะจัดสรรและยกเลิกการจัดสรรโดยอัตโนมัติเมื่อวิธีการเสร็จสิ้นการดำเนินการ
- หากหน่วยความจำนี้เต็ม Java จะพ่นjava.lang.StackOverFlowError
- การเข้าถึงหน่วยความจำนี้ทำได้รวดเร็วเมื่อเทียบกับหน่วยความจำฮีป
- หน่วยความจำนี้ปลอดภัยต่อเธรดเนื่องจากแต่ละเธรดทำงานในสแตกของตัวเอง
3. Heap Space ใน Java
พื้นที่กองในชวาจะใช้สำหรับการจัดสรรหน่วยความจำแบบไดนามิกสำหรับวัตถุ Java และ JRE เรียนที่รันไทม์ วัตถุใหม่จะถูกสร้างขึ้นในพื้นที่ฮีปเสมอและการอ้างอิงถึงวัตถุนี้จะถูกเก็บไว้ในหน่วยความจำสแต็ก
วัตถุเหล่านี้สามารถเข้าถึงได้ทั่วโลกและสามารถเข้าถึงได้จากทุกที่ในแอปพลิเคชัน
โมเดลหน่วยความจำนี้ถูกแบ่งออกเป็นส่วนย่อย ๆ ที่เรียกว่าชั่วอายุคนซึ่ง ได้แก่ :
- Young Generation -นี่คือที่ที่วัตถุใหม่ทั้งหมดได้รับการจัดสรรและอายุ การรวบรวมขยะเล็กน้อยเกิดขึ้นเมื่อสิ่งนี้เต็มไป
- Old หรือ Tenured Generation -นี่คือที่เก็บวัตถุที่มีอายุยืนยาว เมื่อวัตถุถูกเก็บไว้ใน Young Generation จะมีการกำหนดเกณฑ์สำหรับอายุของวัตถุและเมื่อถึงเกณฑ์นั้นวัตถุจะถูกย้ายไปยังรุ่นเก่า
- การสร้างแบบถาวร -ประกอบด้วยข้อมูลเมตาของ JVM สำหรับคลาสรันไทม์และวิธีการสมัคร
ส่วนต่างๆเหล่านี้จะกล่าวถึงในบทความนี้ด้วย - ความแตกต่างระหว่าง JVM, JRE และ JDK
เราสามารถปรับเปลี่ยนขนาดของหน่วยความจำฮีปได้เสมอตามความต้องการของเรา สำหรับข้อมูลเพิ่มเติมโปรดไปที่บทความ Baeldung ที่เชื่อมโยงนี้
3.1. คุณสมบัติที่สำคัญของ Java Heap Memory
นอกเหนือจากสิ่งที่เราได้พูดถึงไปแล้วคุณสมบัติอื่น ๆ ของ heap space มีดังต่อไปนี้:
- เข้าถึงได้โดยใช้เทคนิคการจัดการหน่วยความจำที่ซับซ้อนซึ่งรวมถึง Young Generation, Old หรือ Tenured Generation และ Permanent Generation
- หากพื้นที่ฮีปเต็ม Java จะพ่นjava.lang.OutOfMemoryError
- การเข้าถึงหน่วยความจำนี้ค่อนข้างช้ากว่าหน่วยความจำแบบสแต็ก
- หน่วยความจำนี้ตรงกันข้ามกับสแต็กจะไม่ถูกจัดสรรโดยอัตโนมัติ จำเป็นต้องใช้ Garbage Collector เพื่อเพิ่มวัตถุที่ไม่ได้ใช้เพื่อรักษาประสิทธิภาพของการใช้งานหน่วยความจำ
- ซึ่งแตกต่างจากสแต็กคือฮีปไม่ใช่เธรดที่ปลอดภัยและจำเป็นต้องได้รับการปกป้องโดยการซิงโครไนซ์โค้ดอย่างถูกต้อง
4. ตัวอย่าง
จากสิ่งที่เราได้เรียนรู้ไปแล้วเรามาวิเคราะห์โค้ด Java แบบง่าย ๆ และประเมินวิธีจัดการหน่วยความจำที่นี่:
class Person { int id; String name; public Person(int id, String name) { this.id = id; this.name = name; } } public class PersonBuilder { private static Person buildPerson(int id, String name) { return new Person(id, name); } public static void main(String[] args) { int id = 23; String name = "John"; Person person = null; person = buildPerson(id, name); } }
มาวิเคราะห์ทีละขั้นตอน:
- เมื่อเข้าสู่เมธอดmain ()ช่องว่างในหน่วยความจำสแต็กจะถูกสร้างขึ้นเพื่อจัดเก็บข้อมูลพื้นฐานและการอ้างอิงของวิธีนี้
- ค่าดั้งเดิมของรหัสจำนวนเต็มจะถูกเก็บไว้ในหน่วยความจำสแตกโดยตรง
- บุคคลที่เป็นตัวแปรอ้างอิงประเภทบุคคลจะถูกสร้างขึ้นในหน่วยความจำสแต็กซึ่งจะชี้ไปที่วัตถุจริงในฮีป
- การเรียกใช้ตัวสร้างพารามิเตอร์Person (int, String)จากmain ()จะจัดสรรหน่วยความจำเพิ่มเติมที่ด้านบนของสแต็กก่อนหน้า สิ่งนี้จะจัดเก็บ:
- การอ้างอิงอ็อบเจ็กต์นี้ของอ็อบเจ็กต์การเรียกในหน่วยความจำสแตก
- รหัสค่าดั้งเดิมในหน่วยความจำสแต็ก
- ตัวแปรอ้างอิงของชื่ออาร์กิวเมนต์Stringซึ่งจะชี้ไปยังสตริงจริงจากสตริงพูลในหน่วยความจำฮีป
- หลักวิธีการที่เพิ่มเติมโทรbuildPerson ()วิธีการแบบคงที่จัดสรรต่อไปจะเกิดขึ้นในหน่วยความจำสแต็คที่ด้านบนของหนึ่งก่อนหน้านี้ สิ่งนี้จะจัดเก็บตัวแปรในลักษณะที่อธิบายไว้ข้างต้นอีกครั้ง
- อย่างไรก็ตามสำหรับวัตถุที่สร้างขึ้นใหม่คนประเภทบุคคล , เช่นตัวแปรทั้งหมดจะถูกเก็บไว้ในหน่วยความจำกอง
การจัดสรรนี้อธิบายไว้ในแผนภาพนี้:

5. สรุป
ก่อนที่เราจะสรุปบทความนี้เรามาสรุปความแตกต่างระหว่าง Stack Memory และ Heap Space อย่างรวดเร็ว:
พารามิเตอร์ | หน่วยความจำกอง | พื้นที่กอง |
---|---|---|
ใบสมัคร | Stack is used in parts, one at a time during execution of a thread | The entire application uses Heap space during runtime |
Size | Stack has size limits depending upon OS and is usually smaller then Heap | There is no size limit on Heap |
Storage | Stores only primitive variables and references to objects that are created in Heap Space | All the newly created objects are stored here |
Order | It is accessed using Last-in First-out (LIFO) memory allocation system | This memory is accessed via complex memory management techniques that include Young Generation, Old or Tenured Generation, and Permanent Generation. |
Life | Stack memory only exists as long as the current method is running | Heap space exists as long as the application runs |
Efficiency | Comparatively much faster to allocate when compared to heap | Slower to allocate when compared to stack |
Allocation/Deallocation | หน่วยความจำนี้จะถูกจัดสรรและยกเลิกการจัดสรรโดยอัตโนมัติเมื่อมีการเรียกและส่งคืนเมธอดตามลำดับ | พื้นที่ฮีปจะถูกจัดสรรเมื่อวัตถุใหม่ถูกสร้างและยกเลิกการจัดสรรโดย Gargabe Collector เมื่อไม่ได้อ้างอิงอีกต่อไป |
6. บทสรุป
กองซ้อนและฮีปเป็นสองวิธีที่ Java จัดสรรหน่วยความจำ ในบทความนี้เราเข้าใจวิธีการทำงานและเวลาที่ควรใช้เพื่อพัฒนาโปรแกรม Java ที่ดีขึ้น
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการจัดการหน่วยความจำใน Java โปรดอ่านบทความนี้ที่นี่ นอกจากนี้เรายังได้กล่าวถึง JVM Garbage Collector ซึ่งจะกล่าวถึงโดยย่อในบทความนี้