0Pricing
Go Academy · บทเรียน

ภายในตัวเก็บขยะ

การทำเครื่องหมายและกวาดแบบสามสี GOGC และช่วงหยุดของ GC

ภายในตัวเก็บขยะ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

การทำเครื่องหมายและกวาดแบบสามสี

GC ของ Go ใช้อัลกอริทึมการทำเครื่องหมายและกวาดแบบสามสีที่ทำงานพร้อมกัน ออบเจ็กต์จะมีสถานะสีขาว (ยังไม่ถูกเยี่ยมชม) สีเทา (พบแล้วแต่ยังไม่ได้สแกนลูก) หรือสีดำ (สแกนครบแล้ว) ออบเจ็กต์สีขาวคือขยะเมื่อเริ่มการกวาด

GC แบบทำงานพร้อมกัน

GC ของ Go ทำงานพร้อมกับ goroutine ของแอปพลิเคชันเป็นส่วนใหญ่ จึงลดช่วงหยุดการทำงานของโลกหรือ STW ให้เหลือต่ำกว่าหนึ่งมิลลิวินาทีในโปรแกรมส่วนใหญ่

สิ่งกีดขวางการเขียน

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

ระยะ STW

มีช่วงหยุด STW สั้น ๆ สองครั้งต่อรอบ GC: (1) การเตรียมการทำเครื่องหมาย (เปิดสิ่งกีดขวางการเขียนและบันทึกภาพสแนปชอตของสแตก goroutine) (2) การสิ้นสุดการทำเครื่องหมาย (ตรวจสอบให้แน่ใจว่าสแกนวัตถุสีเทาครบทั้งหมด) ค่า P99 โดยทั่วไปคือ <1ms

GOGC

ทริกเกอร์ GC ควบคุมด้วย GOGC (ค่าเริ่มต้นคือ 100) ซึ่งหมายถึงให้ทำ GC เมื่อขนาดฮีปที่ยังมีชีวิตเพิ่มเป็นสองเท่าจากการทำ GC ครั้งก่อน การตั้งค่า GOGC=50 จะทำให้ GC ทำงานบ่อยขึ้นและใช้หน่วยความจำน้อยลง ส่วน GOGC=200 จะทำให้ GC ทำงานน้อยลงและใช้หน่วยความจำมากขึ้น

GOMEMLIMIT

GOMEMLIMIT (Go 1.19 ขึ้นไป) กำหนดขีดจำกัดหน่วยความจำแบบนุ่มนวล เมื่อฮีปเข้าใกล้ขีดจำกัด GC จะทำงานถี่ขึ้นโดยไม่ขึ้นกับ GOGC ใช้เพื่อป้องกันการถูกยุติการทำงานด้วย OOM ในสภาพแวดล้อมที่มีหน่วยความจำจำกัด

import "runtime/debug"
debug.SetMemoryLimit(512 * 1024 * 1024)

การกำหนดจังหวะ

GC จะกำหนดจังหวะการทำงานของตัวเองเพื่อทำเครื่องหมายให้เสร็จก่อนที่ฮีปจะเต็มขึ้นตามสัดส่วนของ GOGC หากอัตราการจองหน่วยความจำสูง GC จะเพิ่มจำนวนโกโรทีนที่ช่วยทำเครื่องหมาย (การช่วยทำเครื่องหมาย)

runtime.GC()

การเรียก runtime.GC() จะบังคับให้เกิดรอบ GC ทันที มีประโยชน์ในการทดสอบเพื่อให้แน่ใจว่าฟังก์ชันปิดท้ายทำงาน หรือใช้ในการวัดประสิทธิภาพเพื่อเริ่มต้นด้วยฮีปที่สะอาด ไม่ควรเรียกใช้ในระบบจริง

ฟังก์ชันปิดท้าย

ลงทะเบียนฟังก์ชันให้ทำงานเมื่อออบเจ็กต์ถูกเก็บคืนโดยตัวเก็บขยะด้วย runtime.SetFinalizer ฟังก์ชันปิดท้ายจะทำงานในโกโรทีนเฉพาะหลังจาก GC หลีกเลี่ยงการใช้ฟังก์ชันเหล่านี้เพื่อล้างทรัพยากร — ให้ใช้เมธอด Close() แทน

เมตริก GC

อ่านสถิติ GC จาก runtime.ReadMemStats หรือเผยแพร่สถิติเหล่านี้ผ่านเมตริกของ Prometheus ฟิลด์สำคัญ ได้แก่ NumGC, PauseNs, HeapAlloc และ HeapInuse

var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("GC cycles: %d, last pause: %dns\n", m.NumGC, m.PauseNs[(m.NumGC+255)%256])

ตัวเรียกคืนหน่วยความจำ

ตัวเรียกคืนหน่วยความจำเบื้องหลังจะคืนหน่วยความจำฮีปที่ไม่ได้ใช้งานให้ OS ตัวเรียกคืนนี้ทำงานพร้อมกันและกำหนดจังหวะเพื่อไม่ให้กระทบต่อประสิทธิภาพของการทำงานเบื้องหน้า โดยใช้การเรียกระบบ MADV_FREE หรือ MADV_DONTNEED

ตรวจสอบความเข้าใจอย่างรวดเร็ว

GOMEMLIMIT ทำหน้าที่อะไรใน Go 1.19 ขึ้นไป

สรุป: ภายในของ GC

ประเด็นสำคัญ:

  • การทำเครื่องหมายแบบสามสีและการกวาดล้างที่ทำงานพร้อมกัน มีช่วงหยุดการทำงานของโลก (STW) สั้น ๆ สองครั้ง
  • GOGC ควบคุมอัตราการเพิ่มขนาดฮีป โดยค่าเริ่มต้นคือ 100 (เมื่อเพิ่มขึ้น 100% จะทริกเกอร์ GC)
  • GOMEMLIMIT ช่วยให้หน่วยความจำของคอนเทนเนอร์ปลอดภัย (Go 1.19 ขึ้นไป)
  • ใช้ runtime.ReadMemStats สำหรับเมตริก GC

คำถามที่พบบ่อย

บทเรียน “ภายในตัวเก็บขยะ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ภายในตัวเก็บขยะ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ภายในตัวเก็บขยะ”

การทำเครื่องหมายและกวาดแบบสามสี GOGC และช่วงหยุดของ GC คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ภายในตัวเก็บขยะ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม

ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. สแตกกับฮีปและการวิเคราะห์การหลุดพ้น
  2. โมเดลหน่วยความจำของ Go และ Happens-Before
  3. ภายในตัวเก็บขยะ
  4. ลดการจัดสรร: sync.Pool และ Arena
← กลับไปที่ Go Academy