เมื่อคนๆ หนึ่งเริ่มเรียน Java หรือภาษาโปรแกรมอื่นๆ เขาจะเข้ามาติดต่อกับฮีปและสแต็ก เนื่องจากไม่มีคำอธิบายที่ชัดเจนในตอนแรก หลายๆ คนคงมีคำถามมากมายว่า ฮีปคืออะไร สแต็กคืออะไร และฮีปและสแต็กแตกต่างกันอย่างไร ที่แย่กว่านั้นคือมีสแต็กใน Java ซึ่งเป็นโครงสร้างข้อมูลตามลำดับแบบเข้าก่อนออกก่อน (เข้าก่อนออกก่อน) ซึ่งก็คือ java.util.Stack ในกรณีนี้คงทำให้หลาย ๆ คนสับสนมากขึ้นกับคำถามก่อนหน้านี้อย่างหลีกเลี่ยงไม่ได้ ในความเป็นจริง ฮีปและสแต็กเป็นทั้งส่วนของหน่วยความจำและมีฟังก์ชันที่แตกต่างกัน และโปรแกรมจำเป็นต้องจัดสรรหน่วยความจำในพื้นที่นี้ อย่างที่เราทราบกันดีว่าโปรแกรม Java ทั้งหมดทำงานภายในเครื่องเสมือน JVM สิ่งที่เราแนะนำในที่นี้คือฮีปและสแต็กในหน่วยความจำ JVM (เสมือน)
ความแตกต่าง
ความแตกต่างระหว่างฮีปและสแต็กใน Java นั้นเป็นคำถามที่พบบ่อยในการสัมภาษณ์ ประเด็นต่อไปนี้คือความแตกต่างที่เฉพาะเจาะจง
ทุกคนปฏิบัติหน้าที่ของตน
ข้อแตกต่างที่สำคัญคือหน่วยความจำสแต็กใช้เพื่อจัดเก็บตัวแปรภายในเครื่องและการเรียกเมธอด
หน่วยความจำฮีปใช้เพื่อจัดเก็บวัตถุใน Java ไม่ว่าจะเป็นตัวแปรสมาชิก ตัวแปรภายในเครื่อง หรือตัวแปรคลาส ออบเจ็กต์ที่ชี้ไปจะถูกจัดเก็บไว้ในหน่วยความจำฮีป
พิเศษหรือใช้ร่วมกัน
หน่วยความจำสแต็กเป็นของเธรดเดียว แต่ละเธรดจะมีหน่วยความจำสแต็ก และตัวแปรที่เก็บไว้จะมองเห็นได้เฉพาะในเธรดที่เป็นเจ้าของเท่านั้น กล่าวคือ หน่วยความจำสแต็กสามารถเข้าใจได้ว่าเป็นหน่วยความจำส่วนตัวของเธรด
ออบเจ็กต์ในหน่วยความจำฮีปจะปรากฏแก่ทุกเธรด เธรดทั้งหมดสามารถเข้าถึงออบเจ็กต์ในหน่วยความจำฮีปได้
ข้อผิดพลาดข้อยกเว้น
หากไม่มีพื้นที่ว่างในหน่วยความจำสแต็กเพื่อจัดเก็บการเรียกเมธอดและตัวแปรโลคัล JVM จะส่ง java.lang.StackOverFlowError
และหากไม่มีพื้นที่ว่างในหน่วยความจำฮีปสำหรับจัดเก็บอ็อบเจ็กต์ที่สร้างขึ้น JVM จะส่ง java.lang.OutOfMemoryError
ขนาดพื้นที่
หน่วยความจำสแต็กมีขนาดเล็กกว่าหน่วยความจำฮีปมาก หากคุณใช้การเรียกซ้ำ สแต็กของคุณจะเต็มอย่างรวดเร็ว ถ้าการเรียกซ้ำไม่แบ่งออกทันเวลา ปัญหา StackOverFlowError มีแนวโน้มที่จะเกิดขึ้น
คุณสามารถตั้งค่าขนาดหน่วยความจำสแต็กด้วยตัวเลือก -Xss ตัวเลือก -Xms ตั้งค่าขนาดเริ่มต้นของฮีป และตัวเลือก -Xmx ตั้งค่าขนาดฮีปสูงสุด
นี่คือความแตกต่างระหว่างฮีปและสแต็คใน Java หากคุณเข้าใจปัญหานี้ดี ก็สามารถช่วยคุณแก้ไขปัญหาการพัฒนา วิเคราะห์หน่วยความจำฮีปและการใช้งานหน่วยความจำสแต็ก และแม้แต่ปรับแต่งประสิทธิภาพได้
ดูค่าเริ่มต้น (อัปเดต)
เมื่อต้องการดูค่าเริ่มต้นของฮีป ใช้รหัสต่อไปนี้ โดยที่ InitialHeapSize คือขนาดของฮีปเริ่มต้น และ MaxHeapSize คือค่าสูงสุดของฮีป
คัดลอกรหัสรหัสดังต่อไปนี้:
13:17 $ java -XX:+PrintFlagsFinal -version |
uintx ErgoHeapSizeLimit = 0 {ผลิตภัณฑ์}
uintx HeapSizePerGCThread = 87241520 {ผลิตภัณฑ์}
uintx InitialHeapSize := 134217728 {ผลิตภัณฑ์}
uintx LargePageHeapSizeThreshold = 134217728 {ผลิตภัณฑ์}
uintx MaxHeapSize := 2147483648 {ผลิตภัณฑ์}
จาวาเวอร์ชัน "1.8.0_25"
สภาพแวดล้อมรันไทม์ Java(TM) SE (บิลด์ 1.8.0_25-b17)
Java HotSpot(TM) เซิร์ฟเวอร์ 64 บิต VM (บิลด์ 25.25-b02 โหมดผสม)
ตรวจสอบค่าเริ่มต้นของสแต็ก โดยที่ ThreadStackSize คือขนาดของหน่วยความจำสแต็ก
คัดลอกรหัสรหัสดังต่อไปนี้:
13:21 $ java -XX:+PrintFlagsFinal -version |
intx CompilerThreadStackSize = 0 {ผลิตภัณฑ์ pd}
intx ThreadStackSize = 1,024 {ผลิตภัณฑ์ pd}
intx VMThreadStackSize = 1,024 {ผลิตภัณฑ์ pd}
จาวาเวอร์ชัน "1.8.0_25"
สภาพแวดล้อมรันไทม์ Java(TM) SE (บิลด์ 1.8.0_25-b17)
Java HotSpot(TM) เซิร์ฟเวอร์ 64 บิต VM (บิลด์ 25.25-b02 โหมดผสม)
ข้อมูลการแปล
ข้อความภาษาอังกฤษต้นฉบับ: http://javarevisited.blogspot.com.au/2013/01/difference-between-stack-and-heap-java.html
การแปลได้รับการแก้ไข จัดระเบียบ และลบตามข้อความต้นฉบับ หากสนใจสามารถเข้าไปเยี่ยมชมข้อความต้นฉบับได้ ที่อยู่ PS ถูกบล็อก