ویرگول
ورودثبت نام
رامتین قبادی
رامتین قبادیرامتین قبادی هستم. در حدود ۱۷ سال هست در حوزه نرم افزار کار میکنم . دوست دارم در محیط ویرگول یکسری مطالب آموزشی منتشر کنم.
رامتین قبادی
رامتین قبادی
خواندن ۴ دقیقه·۱۹ روز پیش

الگوریتم سه‌رنگ (Tricolor) در Garbage Collector زبان Go — یک راهنمای کامل و ساده


Garbage Collector یا همان بازیافت‌کنندهٔ حافظه یکی از مهم‌ترین بخش‌های زبان Go است؛ بخشی که به‌طور خودکار حافظهٔ بلااستفاده را آزاد می‌کند تا برنامه‌ها سریع، مطمئن و بدون نشت حافظه اجرا شوند. با اینکه Go یک زبان مدرن و سطح بالا است، اما در پشت صحنه از یکی از پیچیده‌ترین و کارآمدترین تکنیک‌های جمع‌آوری زباله یعنی الگوریتم سه‌رنگ (Tricolor Mark-and-Sweep) استفاده می‌کند.

در این مطلب، این الگوریتم را به زبانی ساده، کاربردی و مناسب برنامه‌نویسان Go بررسی می‌کنیم؛ الگوریتمی که بدون دانستن آن هم می‌توانید کدنویسی کنید، اما با دانستن آن کدهای بهینه‌تر، پایدارتر و سریع‌تری خواهید نوشت.

الگوریتم سه‌رنگ چیست؟

این الگوریتم برای تشخیص اشیائی که دیگر مورد استفادهٔ برنامه نیستند و می‌توان آن‌ها را از حافظه حذف کرد به‌کار می‌رود. چرا اسم آن سه‌رنگ است؟
چون هر شیء در Heap در یکی از سه وضعیت قرار می‌گیرد:

1. اشیاء سفید (White)

  • هنوز بررسی نشده‌اند

  • ممکن است زباله باشند

  • اگر تا پایان چرخه بررسی نشوند → حذف می‌شوند

2. اشیاء سیاه (Black)

  • به‌طور کامل بررسی شده‌اند

  • تمام اشاره‌گرهایشان اسکن شده

  • قطعاً زنده و مورد استفاده هستند

  • حذف نمی‌شوند

3. اشیاء خاکستری (Grey)

  • زنده هستند

  • ولی هنوز بررسی نشده‌اند که به چه اشیائی اشاره می‌کنند

  • باید توسط GC اسکن شوند

تنها اشیائی که واقعاً «قابل دسترس» نیستند، در نهایت در مجموعه سفید باقی می‌مانند و حذف می‌شوند.

چرخهٔ کار چگونه است؟ (Mark Phase)

برای شروع، Go GC همه اشیا را سفید در نظر می‌گیرد.
سپس الگوریتم مراحل زیر را طی می‌کند:

1. یافتن ریشه‌ها (Roots)

ریشه‌ها شامل:

  • متغیرهای global

  • متغیرهای موجود روی stack

  • goroutine‌ها

  • اشاره‌گرهای static

این‌ها همیشه قابل دسترس‌اند، بنابراین خاکستری می‌شوند.

2. پردازش اشیاء خاکستری

الگوریتم یک شیء خاکستری برمی‌دارد:

  • آن را سیاه می‌کند

  • تمام اشاره‌گرهای آن را بررسی می‌کند

  • اگر اشاره‌ای به اشیاء سفید وجود داشت → آن‌ها را خاکستری می‌کند

این چرخه آن‌قدر تکرار می‌شود تا هیچ شیء خاکستری باقی نماند.

مرحله پاکسازی (Sweep Phase)

هنگامی که دیگر هیچ شیء خاکستری وجود نداشته باشد:

  • تمام اشیاء زنده → سیاه

  • تمام اشیاء غیرقابل دسترس → سفید

در این لحظه، مجموعه سفید حذف می‌شود و حافظهٔ آن آزاد می‌گردد.

نقش Write Barrier چیست؟

از آنجا که Garbage Collection در Go همزمان با اجرای برنامه (Concurrent GC) انجام می‌شود، ممکن است برنامه در حین اجرای GC، اشاره‌گرهای جدیدی ایجاد یا تغییر دهد.

برای جلوگیری از بهم خوردن فرآیند، یک «سد نوشتن» (Write Barrier) فعال است که:

  • هر time یک اشاره‌گر در heap تغییر کند

  • هدف جدید را خاکستری می‌کند

  • و باعث می‌شود برنامه هیچ‌وقت سیاه → سفید را نقض نکند

این نکته بسیار حیاتی است زیرا:

«هیچ شیء سیاه نباید به شیء سفید اشاره کند.»

اگر این اصل نقض شود، GC ممکن است شیء زنده را اشتباهی پاک کند.

چرا الگوریتم سه‌رنگ مهم است؟

این الگوریتم مزایای بزرگی برای Go دارد:

✔ اجرای همزمان با برنامه (Concurrent)

برنامه متوقف نمی‌شود یا توقف‌های بسیار کوتاهی دارد.

✔ سرعت بالا

Go برای برنامه‌های پرکاربرد و شبکه‌ای طراحی شده و این الگوریتم باعث عملکرد روان سیستم می‌شود.

✔ نوع‌محور و دقیق (Precise GC)

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 بهینه‌تر، سریع‌تر و بدون باگ حافظه‌ای بنویسید.

garbage collectiongoزبان go
۰
۰
رامتین قبادی
رامتین قبادی
رامتین قبادی هستم. در حدود ۱۷ سال هست در حوزه نرم افزار کار میکنم . دوست دارم در محیط ویرگول یکسری مطالب آموزشی منتشر کنم.
شاید از این پست‌ها خوشتان بیاید