ในระยะสั้น
สแต็กใช้สำหรับการจัดสรรหน่วยความจำแบบสแตติกและฮีปสำหรับการจัดสรรหน่วยความจำแบบไดนามิกซึ่งเก็บไว้ใน RAM ของคอมพิวเตอร์
ในรายละเอียด
สแต็ค
สแต็คเป็นโครงสร้างข้อมูล "LIFO" (เข้าก่อนออกก่อน) ที่ได้รับการจัดการและปรับให้เหมาะสมโดย CPU อย่างใกล้ชิด ทุกครั้งที่ฟังก์ชั่นประกาศตัวแปรใหม่มันจะ "ผลัก" ไปยังสแต็ก จากนั้นทุกครั้งที่ออกจากฟังก์ชันตัวแปรทั้งหมดที่ถูกผลักลงบนสแต็กโดยฟังก์ชันนั้นจะถูกปล่อยให้เป็นอิสระ (กล่าวคือพวกมันถูกลบ) เมื่อตัวแปรสแต็กถูกปลดปล่อยพื้นที่หน่วยความจำนั้นจะพร้อมใช้งานสำหรับตัวแปรสแต็กอื่น ๆ
ข้อดีของการใช้สแต็กเพื่อเก็บตัวแปรคือหน่วยความจำนั้นได้รับการจัดการสำหรับคุณ คุณไม่จำเป็นต้องจัดสรรหน่วยความจำด้วยตนเองหรือปล่อยให้เป็นอิสระเมื่อคุณไม่ต้องการมันอีกต่อไป มีอะไรเพิ่มเติมเนื่องจาก CPU จัดระเบียบหน่วยความจำสแต็คอย่างมีประสิทธิภาพการอ่านและการเขียนไปยังตัวแปรสแต็คนั้นรวดเร็วมาก
เพิ่มเติมสามารถพบได้ที่นี่
กอง
ฮีปเป็นส่วนหนึ่งของหน่วยความจำของคอมพิวเตอร์ที่ไม่ได้จัดการโดยอัตโนมัติสำหรับคุณและไม่ได้รับการจัดการโดย CPU อย่างแน่นหนา เป็นพื้นที่หน่วยความจำลอยตัวที่ว่างมากขึ้น (และใหญ่กว่า) ในการจัดสรรหน่วยความจำบนฮีปคุณต้องใช้ malloc () หรือ calloc () ซึ่งเป็นฟังก์ชัน C ในตัว เมื่อคุณจัดสรรหน่วยความจำบนฮีปคุณจะต้องรับผิดชอบในการใช้ฟรี () เพื่อยกเลิกการจัดสรรหน่วยความจำนั้นเมื่อคุณไม่ต้องการใช้อีกต่อไป
หากคุณไม่ทำเช่นนี้โปรแกรมของคุณจะมีสิ่งที่เรียกว่าหน่วยความจำรั่ว นั่นคือหน่วยความจำบนฮีปจะยังคงอยู่ (และจะไม่สามารถใช้ได้กับกระบวนการอื่น) ดังที่เราจะเห็นในส่วนการดีบักมีเครื่องมือที่เรียกว่าValgrindที่สามารถช่วยคุณตรวจจับการรั่วไหลของหน่วยความจำ
แตกต่างจากสแต็คฮีปไม่มีข้อ จำกัด ขนาดของขนาดตัวแปร (นอกเหนือจากข้อ จำกัด ทางกายภาพที่ชัดเจนของคอมพิวเตอร์ของคุณ) หน่วยความจำฮีปช้ากว่าเล็กน้อยในการอ่านและเขียนเนื่องจากต้องใช้พอยน์เตอร์เพื่อเข้าถึงหน่วยความจำบนฮีป เราจะพูดถึงพอยน์เตอร์ในไม่ช้า
แตกต่างจากสแต็คตัวแปรที่สร้างขึ้นบนฮีปสามารถเข้าถึงได้โดยฟังก์ชั่นทุกที่ในโปรแกรมของคุณ ตัวแปรฮีปนั้นอยู่ในขอบเขตทั่วโลก
เพิ่มเติมสามารถพบได้ที่นี่
ตัวแปรที่จัดสรรในสแต็กจะถูกจัดเก็บโดยตรงไปยังหน่วยความจำและการเข้าถึงหน่วยความจำนี้นั้นรวดเร็วมากและการจัดสรรจะถูกจัดการเมื่อโปรแกรมถูกคอมไพล์ เมื่อฟังก์ชั่นหรือวิธีการเรียกใช้ฟังก์ชั่นอื่นซึ่งจะเรียกฟังก์ชั่นอื่นฟังก์ชั่นอื่น ๆ การดำเนินการของฟังก์ชั่นเหล่านั้นยังคงถูกระงับจนกว่าฟังก์ชั่นสุดท้ายจะส่งกลับค่าของมัน สแต็กถูกสงวนไว้เสมอตามลำดับ LIFO บล็อกที่ถูกจองล่าสุดมักจะเป็นบล็อกถัดไปที่จะทำให้เป็นอิสระเสมอ สิ่งนี้ทำให้ง่ายต่อการติดตามสแต็กการปลดบล็อกจากสแต็กนั้นไม่มีอะไรมากไปกว่าการปรับตัวชี้เดียว
ตัวแปรที่จัดสรรในฮีปจะมีการจัดสรรหน่วยความจำในขณะใช้งานและการเข้าถึงหน่วยความจำนี้จะช้าลงเล็กน้อย แต่ขนาดฮีปจะถูก จำกัด ด้วยขนาดของหน่วยความจำเสมือนเท่านั้น องค์ประกอบของฮีปไม่มีการพึ่งพาซึ่งกันและกันและสามารถเข้าถึงแบบสุ่มได้ตลอดเวลา คุณสามารถจัดสรรบล็อกได้ตลอดเวลาและฟรีบล็อกเมื่อใดก็ได้ สิ่งนี้ทำให้มีความซับซ้อนมากขึ้นในการติดตามว่าส่วนใดของฮีปถูกจัดสรรหรือว่างในเวลาใดก็ตาม
คุณสามารถใช้สแต็กได้หากคุณทราบจำนวนข้อมูลที่คุณต้องการจัดสรรก่อนรวบรวมเวลาและไม่ใหญ่เกินไป คุณสามารถใช้ฮีปได้หากคุณไม่ทราบจำนวนข้อมูลที่แน่นอนที่คุณต้องใช้ในรันไทม์หรือหากคุณต้องการจัดสรรข้อมูลจำนวนมาก
ในสถานการณ์แบบมัลติเธรดแต่ละเธรดจะมีสแต็กที่เป็นอิสระโดยสมบูรณ์ แต่จะแบ่งใช้ฮีป สแต็กเป็นเฉพาะเธรดและฮีปเป็นแอปพลิเคชันเฉพาะ สแต็กเป็นสิ่งสำคัญที่ต้องพิจารณาในการจัดการข้อยกเว้นและการดำเนินการเธรด
แต่ละเธรดจะได้รับสแต็กโดยทั่วไปจะมีฮีปเดียวสำหรับแอปพลิเคชัน (แม้ว่าจะไม่ใช่เรื่องแปลกที่จะมีหลายฮีปสำหรับการจัดสรรประเภทต่างๆ)
ณ รันไทม์ถ้าแอ็พพลิเคชันต้องการฮีปเพิ่มเติมสามารถจัดสรรหน่วยความจำจากหน่วยความจำว่างและหากสแต็กต้องการหน่วยความจำมันสามารถจัดสรรหน่วยความจำจากหน่วยความจำที่จัดสรรหน่วยความจำว่างสำหรับแอปพลิเคชัน
แม้รายละเอียดเพิ่มเติมจะได้รับที่นี่และที่นี่
ตอนนี้มาถึงคำตอบของคำถามของคุณ
มีการควบคุมโดย OS หรือรันไทม์ภาษาในระดับใด
ระบบปฏิบัติการจะจัดสรรสแต็กสำหรับแต่ละเธรดระดับระบบเมื่อสร้างเธรด โดยทั่วไประบบปฏิบัติการจะถูกเรียกใช้โดย runtime ภาษาเพื่อจัดสรรฮีปสำหรับแอปพลิเคชัน
เพิ่มเติมสามารถพบได้ที่นี่
ขอบเขตของพวกเขาคืออะไร?
ได้รับแล้วในด้านบน
"คุณสามารถใช้สแต็กถ้าคุณรู้ว่าต้องใช้ข้อมูลเท่าไหร่ในการรวบรวมก่อนรวบรวมและมันก็ไม่ใหญ่เกินไปคุณสามารถใช้ฮีปได้ถ้าคุณไม่รู้ว่าจะต้องใช้ข้อมูลมากแค่ไหนในรันไทม์หรือถ้า คุณต้องจัดสรรข้อมูลเป็นจำนวนมาก "
เพิ่มเติมสามารถพบได้ในที่นี่
อะไรเป็นตัวกำหนดขนาดของแต่ละคน
ขนาดของสแต็กถูกตั้งค่าโดยระบบปฏิบัติการเมื่อสร้างเธรด ขนาดของฮีปถูกตั้งค่าเมื่อเริ่มต้นแอปพลิเคชัน แต่สามารถขยายได้ตามต้องการพื้นที่ (ตัวจัดสรรต้องการหน่วยความจำเพิ่มเติมจากระบบปฏิบัติการ)
อะไรทำให้เร็วขึ้น
การจัดสรรสแต็กนั้นเร็วกว่ามากเนื่องจากทั้งหมดนี้คือการย้ายตัวชี้สแต็ก การใช้พูลหน่วยความจำคุณสามารถรับประสิทธิภาพเทียบเคียงได้จากการจัดสรรฮีป แต่ที่มาพร้อมกับความซับซ้อนที่เพิ่มขึ้นเล็กน้อยและอาการปวดหัวของมันเอง
นอกจากนี้ stack vs. heap ไม่เพียง แต่คำนึงถึงประสิทธิภาพเท่านั้น มันยังบอกคุณมากเกี่ยวกับอายุการใช้งานของวัตถุที่คาดหวัง
รายละเอียดสามารถพบได้จากที่นี่