پرش به مطلب اصلی

Memory_mangement_in_go

در ابتدا باید بگم که یکی از راه های مدیریت مموری که به صورت اتوماتیک انجام میشه. [[Notes/Software/General/Garbage Collection|Garbage Collection]] هستش. که از تکنیک های [[Notes/Software/General/Garbage Collection#Mark and Sweep|Mark and sweep]] و [[Notes/Software/General/Garbage Collection#Tri-color|Tri-color]] در گولنگ استفاده میشه. توی گو gc بصورت موازی با اجرای برنامه اجرا میشه و latency که برای GC هست و خیلی کم میکنه این کار به لطف write barrier انجام میشه

[[01. Interview question#4. چه تکنیک‌هایی برای کاهش فشار Garbage Collector (GC) می‌شناسی؟]]

GC Cycle

۱. راه‌اندازی و آماده‌سازی علامت‌گذاری (Initialization & Mark Setup - STW)

  • توقف کل (Stop-The-World):
    در این مرحله، اجرای برنامه به‌طور موقت متوقف می‌شود تا جمع‌آورنده زباله بتواند اقدامات اولیه لازم را انجام دهد. این توقف به دلیل اهمیت دقت در جمع‌آوری «ریشه‌های GC» (GC roots) مانند متغیرهای سراسری، پشته‌های (stacks) گوروتین‌ها و رجیسترها، انجام می‌شود.

  • هدف:

    • شناسایی تمام ریشه‌های GC.
    • راه‌اندازی ساختارهای داخلی مورد نیاز برای فاز علامت‌گذاری.

۲. فاز علامت‌گذاری همزمان (Concurrent Mark Phase)

  • علامت‌گذاری همزمان:
    پس از راه‌اندازی اولیه، فاز علامت‌گذاری آغاز می‌شود. در این مرحله،GC به‌طور همزمان با اجرای برنامه شروع به پیمایش حافظه میکنه تا اشیا قابل دسترسی رو علامت‌گذاری کنه و ۲۵درصد منابع پردازشی هم میگیره

  • اجرای موازی:
    برنامه همچنان به اجرای عادی خود ادامه می‌دهد؛ به عبارت دیگر، علامت‌گذاری به‌صورت concurrent (همزمان) انجام می‌شود تا توقف طولانی در برنامه ایجاد نشود. البته ممکنه یه گورتینی سرعت نوشتنش از سرعت علامت گذاری ما بیشتر باشه. مفهوم Mark Assist اینجوریه که وقتی سرعت تخصیص حافظه (یا به عبارت دیگر «نوشتن» در حافظه توسط گوروتین‌ها) از سرعت علامت‌گذاری (Marking) پیشی می‌گیره، سیستم به‌طور خودکار از گوروتین‌ها می‌خواهد تا مقداری از کار علامت‌گذاری رو هم انجام بدن. به عبارت ساده‌تر:

    • اMark Assist باعث میشه که وقتی گوروتین‌ها مشغول تخصیص حافظه هستند، قسمتی از آن تخصیص به انجام کارهای مربوط به علامت‌گذاری اختصاص پیدا کنه.
    • این کار باعث میشه سرعت تخصیص (نوشتن) کمی کند بشه تا علامت‌گذاری هم به موقع پیش بره و از عقب افتادن آن جلوگیری شود.
    • به این ترتیب، سرعت تخصیص حافظه و سرعت علامت‌گذاری به‌طور هماهنگ با هم پیش میره.
  • مکانیزم Write Barrier:

    • وظیفه: هنگام تغییر یا به‌روزرسانی اشاره‌گرها توسط برنامه، write barrier فعال می‌شود.
    • اهمیت: این مکانیزم اطمینان حاصل می‌کند که اگر یک اشاره‌گر به شیء جدیدی تغییر کند، آن شیء به عنوان شیء زنده علامت‌گذاری شود. این کار از از دست رفتن اشیاء زنده به دلیل تغییرات در حافظه جلوگیری می‌کند.
  • نتیجه:
    تضمین می‌شود که تمام اشیاء قابل دسترس حتی در حین به‌روز‌رسانی‌های مداوم توسط برنامه، به درستی علامت‌گذاری شوند.


۳. خاتمه علامت‌گذاری (Mark Termination - STW)

  • توقف نهایی (Stop-The-World):
    در پایان فاز علامت‌گذاری همزمان، یک توقف کوتاه دیگر رخ می‌دهد. در این مرحله، برنامه برای مدتی دوباره متوقف می‌شود تا جمع‌آورنده زباله بتواند مراحل پایانی علامت‌گذاری را به اتمام برساند.

  • هدف:

    • اطمینان از اینکه تمام اشیاء زنده در حافظه، حتی آنهایی که ممکن است در حین علامت‌گذاری همزمان تغییر کرده باشند، به طور کامل علامت‌گذاری شده‌اند.
    • هماهنگی بین تغییرات اعمال شده توسط write barrier در حین فاز همزمان و وضعیت نهایی حافظه. این تاخییر برای اینه که چون مرحله قبلی به صورت همزمان اجرا میشه

۴. فاز پاکسازی (Sweep Phase)

  • عملیات پاکسازی:
    پس از پایان کامل علامت‌گذاری، جمع‌آورنده زباله وارد فاز پاکسازی می‌شود. در این مرحله، حافظه پیمایش شده و اشیاء بدون علامت شناسایی می‌شوند.

  • آزادسازی حافظه:
    حافظه‌ای که به این اشیاء اختصاص داده شده بود، آزاد شده و به سیستم بازگردانده می‌شود تا برای تخصیص‌های آینده استفاده شود.

  • روش تدریجی (Incremental Sweeping):
    برای جلوگیری از توقف‌های طولانی و ایجاد فشار ناگهانی بر روی سیستم، عملیات پاکسازی به‌صورت تدریجی انجام می‌شود. این امر باعث می‌شود که آزادسازی حافظه در بازه‌های زمانی کوچک صورت گیرد. به صورت پیشفرض مقدارش ۱۰۰ درصده یعنی هر موقع مقدار هیپ دوبرابر حالت فعلی شد


۵. فعالیت‌های پس از چرخه (Post-Cycle Activities)

  • تنظیم شمارنده‌ها و آستانه‌های تخصیص:
    پس از اتمام فاز پاکسازی، runtime (زمان اجرای Go) برخی از شمارنده‌ها و آستانه‌های تخصیص حافظه را به‌روزرسانی می‌کند. این اقدامات شامل تنظیم میزان حافظه زنده (live heap) پس از جمع‌آوری و تعیین مقدار حافظه مجاز برای تخصیص قبل از شروع چرخه بعدی GC است.

  • آمادگی برای چرخه بعدی:
    با به‌روزرسانی این متغیرها، سیستم آماده می‌شود تا در زمان مناسب، چرخه بعدی جمع‌آوری زباله را آغاز کند. این تنظیمات کمک می‌کنند تا چرخه‌های GC به‌طور منظم و مطابق با تغییرات بار کاری حافظه انجام شوند.


نکات تکمیلی:

  • پیش‌مداخله (Preemptive GC):
    زمانی gc میتونه کار خودش رو شروع کنه که بتونه همه برنامه رو ببره روی حالت STW مثلا اگر یه گورتین توی یه لوپ بزرگ گیر افتاده بشه نمیتونه کاری کنه اماGo از تکنیک‌Preemptive استفاده می‌کند تا GC به صورت همزمان و بدون ایجاد تأخیر‌های قابل توجه، کار خود را انجام دهد. این بدین معناست که در صورت شناسایی عملیات‌های طولانی توسط برنامه، GC می‌تواند در نقاط امن (safe-points) مداخله کند و بخشی از کار خود را انجام دهد تا از تأخیرهای ناگهانی جلوگیری شود.

  • تأثیر بر عملکرد:
    اگرچه فازهای STW (توقف کل) وجود دارند، طراحی Go به گونه‌ای است که این توقف‌ها بسیار کوتاه و بهینه هستند تا تأثیر قابل توجهی بر کارایی برنامه نداشته باشند.

  • تنظیمات GC Percentage (درصد GC):
    مقدار پیش‌فرض GOGC (معمولاً 100) تعیین می‌کند که پس از اتمام یک چرخه GC، تا چه میزان حافظه می‌تواند رشد کند قبل از آغاز چرخه بعدی. این تنظیم کمک می‌کند تا توازن بین مصرف حافظه و زمان صرف شده برای جمع‌آوری زباله حفظ شود.