قسمت سوم Java Zone- فرآیند Garbage Collection


سلامی دوباره

در این قسمت قراره مبحث GC رو مورد بررسی قرار بدیم.

تعریف: به پروسه ی مدیریت حافظه اتومات برنامه های جاوایی gc میگن.

همونطور که میدونین، برنامه های جاوا بعد کامپایل به بایت کد تبدیل میشن که می تونن روی ماشین مجازی جاوا یا به اختصار JVM اجرا بشن. وقتی برنامه های جاوا روی JVM اجرا می شن، آبجکت ها در مموری هیپ (که در قسمت قبلی توضیح دادم) ایجاد می شن که بخشی از حافظه اختصاص یافته به برنامه است. در نهایت، به برخی از آبجکت ها نیازی نخواهید داشت. garbage collector این آبجکت های بلا استفاده رو پیدا و اون هارو را پاک می کنه تا حافظه آزاد بشه.


نحوه کار garbage collection

این فرآیند یک پروسه ی اتومات است. برنامه نویس نیازی به مشخص کردن آبجکت ها برای پاک کردن نداره. اجرای عملیات gc در JVM موجوده و هر JVM می تونه مجموعه ای از آبجکت ها رو هر طور که بخواد نگهداری کنه. تنها شرط این است که با JVM های مرسوم مطابقت داشته باشه. اگرچه تعداد زیادی JVM وجود داره، اما HotSpot رایج ترین نوع به حساب میاد.



در حالی که HotSpot دارای چندین gc است که برای موارد مختلف استفاده، بهینه شده اما gc های آن از همان روند اساسی پیروی می کنه.

مراحل اصلی gc

در مرحله اول، آبجکت هایی که بدون ارجاع مونده رو شناسایی و علامت گذاری می کنه. در مرحله دوم، آبجکت های شناسایی شده حذف می شوند. در صورت نیاز، حافظه پس از پاک کردن آبجکت ها می تونه فشرده بشه، تا آبجکت های باقی مونده در مموری هیپ در یک فضای پیوسته، کنار هم قرار بگیرن. این فرآیند متراکم سازی، تخصیص مموری برای آبجکت های جدید رو آسان تر میکنه.

استراتژی شناسایی آبجکت ها

همه ی gc های موجود در HotSpot با این استراتژی که آبجکت ها رو بر اساس طول عمرشون دسته بندی میکنه، کار میکنه. دلیل اش اینه که اکثر آبجکت عمر کوتاهی دارن و به زودی پس از ایجاد شدن، برای پروسه gc آماده می شن.

جایگاه یکم: Young Generation

آبجکت تازه ایجاد شده از در اینجا قرار میگیره. این جایگاه به دو قسمت، Eden و باقی مانده تقسیم میشن.

بخش Eden : زمانی که ما یک آبجکت ایجاد می کنیم، JVM جهت تخصیص حافظه از فضای Eden استفاده میکنه.

بخش باقی مانده: در اینجا هم آبجکت هایی که از فرآیند پاکسازی عبور کردن قرار میگیرن.


جایگاه دوم: Old Generation

آبجکت هایی که به حداکثر آستانه تنش برسند، به "فضای تنور" یا "فضای نسل قدیمی" منتقل می شن.

جایگاه سوم: Permanent Generation

کلاس ها و متدها در این قسمت ذخیره میشن و کلاس هایی که مورد استفاده نیستند در این مرحله حذف میشن.


خب بریم سراغ چهار روش مرسوم HotSpot برای عملیات gc


نوع Serial:

تمام رخدادهای gc بصورت سریالی در یک ترد و عملیات متراکم سازی پس از اجرای gc، هر بار انجام می شه.

نوع Parallel:

برای عملیات gc که زیاد سنگین نباشه از چند ترد استفاده میشه و یک ترد برای عملیات gc سنگین تر و متراکم سازی بخش Old Generation در نظر گرفته میشه.

نوع CMS (Concurrent Mark Sweep)

همانند الگوریتم نوع Parallel از چند ترد برای عملیاتی که سنگین نباشند، استفاده میشه. اما فرقی که با حالت قبلی داره اینه که تمام عملیات gc رو همزمان با فرآیندهای برنامه اجرا میکنه تا احتمال وقوع رخداد stop the world رو به شدت کاهش بده. در ضمن در این حالت خبری از متراکم سازی نیست.

  • تمام عملیات جزئی gc رویدادهای "Stop the World" هستن. یعنی تمام تردهای برنامه تا زمان کامل شدن عملیات متوقف می شن.

نوع G1 (Garbage First):

جدیدترین نوع از عملیات gc در این حالت قرار داره. کارها مثل مدل CMS موازی و همزمان انجام میشه اما با این تفاوت که راندمان و بهینه سازی های بهتری نسبت به مدل قبلی داره و کاملا متفاوت عمل میکنه.


مزیت های gc در جاوا:

خب همونطور که گفتم این پروسه یک روال اتومات در جاوا است و مثل بقیه زبان ها (C/C++) نیست که بصورت دستی مدیریت حافظه رو انجام بدیم. اینم بدونید که برای بسیاری از برنامه های ساده، gc چیزی نیست که برنامه نویس بخواد آگاهانه در نظر بگیره. با این حال، برای برنامه نویسانی که می خوان مهارت های جاوا رو ارتقا بدن، درک نحوه کار gc و روش های تنظیم اونها مهمه.

یه نکته مهم هم اینه که

علاوه بر مکانیسم های اساسی gc، غیر قطعی بودن آن هم مهم است و هیچ راهی برای پیش بینی زمان عملیات در زمان اجرا وجود نداره. برای اجرای gc هم میتوان به استفاده از System.gc یا Runtime.gc اشاره کرد، اما هیچ تضمینی برای عملکرد واقعی اون نیست.



امیدوارم از این بخش خوشتون اومده باشه. البته یه قسمت 3 و نیم هم برای ادامه یه سری نکات کوچیک در نظر گرفتم?

تا قسمت 3 و نیم ??