ทำไมบน Linux ที่ทันสมัยขนาดสแต็กเริ่มต้นมีขนาดใหญ่มาก - 8MB (แม้แต่ 10 ในการกระจาย)


10

ตัวอย่างเช่นบน OSX มันน้อยกว่า 512k

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


ฉันสงสัยว่าในขณะที่ฉันตั้งใจจะเปลี่ยนขนาดสแต็คเป็น 512 KiB ในแอปของฉัน - นี่ยังคงฟังดูเหมือนเป็นจำนวนมากสำหรับเรื่องนี้ แต่มันมีขนาดเล็กกว่า 8MiB - และจะทำให้หน่วยความจำเสมือนของกระบวนการลดลงอย่างมีนัยสำคัญ มีเธรดจำนวนมาก (I / O)

ฉันก็รู้ว่ามันไม่เจ็บจริง ๆ อธิบายได้ดีที่นี่ : ขนาดสแต็กเริ่มต้นสำหรับ pthreads


คุณใช้ CPU แบบ 32 บิตหรือไม่ X86_64 CPUs มีพื้นที่ที่อยู่เสมือนสูงถึง 128 terabytes (ในพื้นที่ผู้ใช้) ซึ่งน่าจะเพียงพอสำหรับกอง 8 MB จำนวนมาก
Johan Myréen

@ JohanMyréen - ไม่ x64 เป็น มันไม่ใช่เรื่องใหญ่เลยฉันแค่สงสัยว่าไม่มีเหตุผลจริงที่จะทำเช่นนั้น (ในขณะนี้)
คิริลคิรอฟ

ในปี 2019 และ 8 MiB มีหน่วยความจำมากมาย? ฉันไม่คิดอย่างนั้น การมีขนาดสแต็กเริ่มต้นขนาดใหญ่ทำให้ง่ายต่อการเขียนโปรแกรมด้วยการเรียกซ้ำ ฉันประหลาดใจมากที่รู้ว่าขนาดสแต็คเริ่มต้นบน Windows เพียง 1MiB
oldherl

คำตอบ:


15

อย่างที่คนอื่น ๆ พูดและดังที่ได้กล่าวไว้ในลิงก์ที่คุณให้ไว้ในคำถามของคุณการมีสแต็คขนาด 8MiB จะไม่ทำร้ายอะไรเลย (นอกเหนือจากการใช้พื้นที่ที่อยู่ - บนระบบ 64 บิตที่ไม่สำคัญ)

Linux ใช้สแต็คขนาด 8MiB มาเป็นเวลานาน การเปลี่ยนแปลงได้รับการแนะนำในเวอร์ชั่น 1.3.7ของเคอร์เนลในเดือนกรกฎาคม 2538 ย้อนกลับไปแล้วมันก็ถูกนำเสนอเป็นการแนะนำการ จำกัด ก่อนหน้านี้ไม่มีใคร:

จำกัด การสแต็กตามค่าเริ่มต้นที่มีสติ: รูทสามารถเพิ่มขีด จำกัด นี้ได้ถ้าต้องการ .. 8MB ดูเหมือนสมเหตุสมผล

บน Linux จำกัด สแต็คยังมีผลต่อขนาดของข้อโต้แย้งโปรแกรมและสิ่งแวดล้อมซึ่งจะถูก จำกัด ให้ไตรมาสที่หนึ่งของวงเงินสแต็ค ; เคอร์เนลบังคับใช้อย่างน้อย 32 หน้าสำหรับอาร์กิวเมนต์และสภาพแวดล้อม

สำหรับเธรดหากขีด จำกัด สแต็ก ( RLIMIT_STACK) ไม่ จำกัด ให้pthread_createใช้การ จำกัด ของตัวเองกับสแต็กของเธรดใหม่ - และสำหรับสถาปัตยกรรมส่วนใหญ่นั่นคือน้อยกว่า 8MiB


1
ว้าวน่าสนใจ ฉันคิดว่าเพิ่งเปิดตัว ฉันมีเธรดประมาณ 200 รายการ (เป็นอีกหัวข้อยาวดังนั้นเราจะเพิกเฉยสักครู่) และtopแสดงในผลลัพธ์ VIRT ที่น่ากลัว แม้ว่าการขุดลึกลงไปอีกนิดพื้นที่ส่วนใหญ่ของที่อยู่เสมือนนี้นำมาจากจุดต่อเธรด (หน่วยความจำ) ไม่ใช่จากขนาดสแต็กดังนั้นการลดขนาดสแต็กจะไม่ลดหน่วยความจำเสมือนลงอย่างมาก ฉันแค่อยากรู้ว่าทำไม 8MiB และทำไมมากขนาดนั้น
คิริลคิรอฟ

"8 MB" หมายถึงสแต็กของแต่ละเธรดสามารถขยายได้ถึง 8 MB หากเธรดตัดสินใจใช้ แต่หน่วยความจำกายภาพจะไม่ได้รับการจัดสรรจนกว่าจะใช้หน่วยความจำจริง หากเธรด 200 เธรดของคุณใช้ 512 KB คุณจะใช้ RAM จริง 100 MB ไม่ใช่ 1.6 GB
Guntram Blohm รองรับโมนิก้า

หากคุณไม่ได้ทำการแลกเปลี่ยนคอลัมน์ RES ในtopจะให้คำตอบที่ดีกว่ากับ "หน่วยความจำแบบใดที่กระบวนการนี้ใช้จริง" ที่ VIRT ทำ
kbolino

1
@Guntram the OP ตระหนักดีว่าเห็นลิงค์ในคำถาม
Stephen Kitt

1

8MB เป็นขนาดเสมือนของสแต็ก ความผิดพลาดของหน้าจะเกิดขึ้นเมื่อแอปพลิเคชันของคุณพยายามใช้สแต็กมากกว่าที่ได้รับการจัดสรรในปัจจุบัน ตัวจัดการข้อผิดพลาดหน้าของเคอร์เนลจะจัดสรรหน้าฟิสิคัลแล้วแอปพลิเคชันของคุณจะดำเนินการต่อ

ดูhttps://unix.stackexchange.com/a/280865/21212สำหรับคำอธิบายโดยสมบูรณ์

ดังนั้นการลดขนาดสแต็คของคุณจึงไม่มีผลในการลดการใช้หน่วยความจำกายภาพของแอปพลิเคชันของคุณ


1
ฉันได้เชื่อมโยงคำตอบนี้ในคำถามของฉันแล้ว ฉันยังเขียนด้วยว่าฉันตระหนักถึงสิ่งนี้ แต่นี่ไม่ได้ตอบคำถามจริงๆ ขอบคุณต่อไป
คิริลคิรอฟ

ฉันคิดว่าคุณต้องทบทวนสถานที่ของคำถามอีกครั้งและคำตอบนี้ (ไม่ใช่ -) ชี้ให้เห็นว่าทำไม หน่วยความจำเสมือนไม่ใช่หน่วยความจำจริง ขนาดสแต็กอาจเป็น 800MB และจะไม่มีผลกับการใช้หน่วยความจำจริงเว้นแต่ว่าแอปพลิเคชันของคุณจะสร้างเฟรมสแต็กมากกว่า 8MB
kbolino
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.