Garbage Collector یا همان بازیافتکنندهٔ حافظه یکی از مهمترین بخشهای زبان Go است؛ بخشی که بهطور خودکار حافظهٔ بلااستفاده را آزاد میکند تا برنامهها سریع، مطمئن و بدون نشت حافظه اجرا شوند. با اینکه Go یک زبان مدرن و سطح بالا است، اما در پشت صحنه از یکی از پیچیدهترین و کارآمدترین تکنیکهای جمعآوری زباله یعنی الگوریتم سهرنگ (Tricolor Mark-and-Sweep) استفاده میکند.
در این مطلب، این الگوریتم را به زبانی ساده، کاربردی و مناسب برنامهنویسان Go بررسی میکنیم؛ الگوریتمی که بدون دانستن آن هم میتوانید کدنویسی کنید، اما با دانستن آن کدهای بهینهتر، پایدارتر و سریعتری خواهید نوشت.
این الگوریتم برای تشخیص اشیائی که دیگر مورد استفادهٔ برنامه نیستند و میتوان آنها را از حافظه حذف کرد بهکار میرود. چرا اسم آن سهرنگ است؟
چون هر شیء در Heap در یکی از سه وضعیت قرار میگیرد:
هنوز بررسی نشدهاند
ممکن است زباله باشند
اگر تا پایان چرخه بررسی نشوند → حذف میشوند
بهطور کامل بررسی شدهاند
تمام اشارهگرهایشان اسکن شده
قطعاً زنده و مورد استفاده هستند
حذف نمیشوند
زنده هستند
ولی هنوز بررسی نشدهاند که به چه اشیائی اشاره میکنند
باید توسط GC اسکن شوند
تنها اشیائی که واقعاً «قابل دسترس» نیستند، در نهایت در مجموعه سفید باقی میمانند و حذف میشوند.
برای شروع، Go GC همه اشیا را سفید در نظر میگیرد.
سپس الگوریتم مراحل زیر را طی میکند:
ریشهها شامل:
متغیرهای global
متغیرهای موجود روی stack
goroutineها
اشارهگرهای static
اینها همیشه قابل دسترساند، بنابراین خاکستری میشوند.
الگوریتم یک شیء خاکستری برمیدارد:
آن را سیاه میکند
تمام اشارهگرهای آن را بررسی میکند
اگر اشارهای به اشیاء سفید وجود داشت → آنها را خاکستری میکند
این چرخه آنقدر تکرار میشود تا هیچ شیء خاکستری باقی نماند.
هنگامی که دیگر هیچ شیء خاکستری وجود نداشته باشد:
تمام اشیاء زنده → سیاه
تمام اشیاء غیرقابل دسترس → سفید
در این لحظه، مجموعه سفید حذف میشود و حافظهٔ آن آزاد میگردد.
از آنجا که Garbage Collection در Go همزمان با اجرای برنامه (Concurrent GC) انجام میشود، ممکن است برنامه در حین اجرای GC، اشارهگرهای جدیدی ایجاد یا تغییر دهد.
برای جلوگیری از بهم خوردن فرآیند، یک «سد نوشتن» (Write Barrier) فعال است که:
هر time یک اشارهگر در heap تغییر کند
هدف جدید را خاکستری میکند
و باعث میشود برنامه هیچوقت سیاه → سفید را نقض نکند
این نکته بسیار حیاتی است زیرا:
اگر این اصل نقض شود، GC ممکن است شیء زنده را اشتباهی پاک کند.
این الگوریتم مزایای بزرگی برای Go دارد:
برنامه متوقف نمیشود یا توقفهای بسیار کوتاهی دارد.
Go برای برنامههای پرکاربرد و شبکهای طراحی شده و این الگوریتم باعث عملکرد روان سیستم میشود.
GC دقیقاً میداند کدام دادهها اشارهگر هستند.
برخلاف C++ یا Rust، برنامهنویس نیازی به مدیریت حافظه ندارد.
فرض کنید ساختار زیر وجود دارد:
A → B → C D → E → F
اگر A، B و C از ریشهها قابل دسترس باشند اما هیچ ریشهای به D اشاره نکند:
مجموعه دوم (D و E و F) سفید باقی میماند
بنابراین قابل جمعآوری است
حتی اگر خود E به F اشاره کند، اهمیتی ندارد
چون E خودش قابل دسترس نیست
مثال دیگه:
چرا شیء E قابل جمعآوری است؟

object E سفید است.
object E میتواند F را ببیند، اما هیچ شیء دیگری E را نمیبیند.
یعنی:
هیچ اشارهگری از ریشهها (A، B، C) به سمت E نمیرود
حتی اگر خود E به F اشاره کند، مهم نیست
چون E خودش قابل دسترسی نیست
→ پس E و F (اگر از جای دیگری reachable نباشند) garbage هستند.
این نکته مهم است:
نه اینکه خودش به بقیه دسترسی داشته باشد!
در مثال شما:
A → (اشاره دارد) به چیزهایی
B → ...
C → ...
اما هیچ کدام به E اشاره نمیکنند.
چرا Root Objects همیشه سیاهاند؟
چون:
از دید برنامه همیشه قابل دسترسیاند
اگر آنها سفید باشند، کل برنامه از بین میرود
و نقطه شروع همهٔ reachable objectها هستند
Rootها نقطهٔ ثابت آغاز الگوریتم هستند.
الگوریتم سهرنگ یک بخش کلیدی از سیستم Garbage Collection زبان Go است.
این الگوریتم با دستهبندی اشیاء به سفید، خاکستری و سیاه و بررسی سیستماتیک آنها، تعیین میکند چه اشیایی واقعاً در برنامه قابل دسترس هستند و چه اشیایی باید حذف شوند.
نتیجهٔ استفاده از این الگوریتم:
سرعت بالا
حداقل توقف برنامه
عدم نشت حافظه
پایداری در برنامههای مقیاسپذیر
درک نحوهٔ کار این الگوریتم به شما کمک میکند برنامههای Go بهینهتر، سریعتر و بدون باگ حافظهای بنویسید.