AliReza Beigy
AliReza Beigy
خواندن ۳ دقیقه·۶ سال پیش

زباله جمع کن (GC) در جاوا

چند هفته ی پیش استاد برنامه نویسی پیشرفته کلمه ی GC از دهنش در رفت و باعث شد اولین مطلبم در ویرگول رو به این مورد اختصاص بدم

مقدمه:

تا حالا شده فکر کنید ما توی برنامه هایی که می نویسیم خیلی شی هایی که می سازیم رو به حال خودش ول می کنیم و دیگه ازشون استفاده نمی کنیم چی میشن؟؟ آخه حجمی رو از رم رو اشغال کرده ،پس بهتره یه سیستمی وجود داشته باشه که بتونه این اشیای بی استفاده رو شناسایی کنه و جمع شون کنه

GC چیست؟

در ماشین مجازی جاوا(JVM) یه زباله جمع کن(Garbage Collector) هست که وظیفه ی مدیریت آبجکت های توی حافظه رو داره و آبجکت های بلااستفاده رو پیدا میکنه و اون فضای اشغال شده رو آزاد می کنه، شایان ذکر این فرایند به صورت خودکار در یه ترد کنار برنامه انجام میشه و زمانی که فضای آزاد اختصاص داده شده به برنامه(Heap) به یه حدی برسه این فرایند به صورت خودکار انجام میشه

حافظه Heap چیست؟
به قسمتی از حافظه هست که به صورت مجازی برای ذخیره ی داده های برنامه اختصاص داده میشه

عکس 1
عکس 1




GC چطور کار می کنه؟

زباله جمع کن میاد توی حافظه ی Heap میگرده و آبجکت هایی که کسی باهاشون کاری نداره رو حذف می کنه

عکس 2
عکس 2

توی عکس 2 یه GC Roots هست که در واقع همون طور که می دونید وقتی یه آبجکت جایی استفاده نشده باشه بلااستفاده تشخیص داده میشه پس لازمه که یه سری GC Root هایی وجود داشته باشن تا به این آبجکت ها هویت بدن

در اینجا می تونید انواع GC Root های جاوا رو ببینید


البته به همین سادگی ها هم نیست، در واقع GC میاد یه اسکن می کنه و آبجکت های بلا استفاده رو قبل از حذف به قسمتی مجازی انتقال میده که به اصطلاح بهش میگن Old Generations

عکس 3
عکس 3

توی زبان های سطح پایین این عملیات رو به صورت دستی باید انجام بدن در حالی که شما دیگه نیاز به همچین کاری ندارید

توی جاوا هم اگه بخواید دستی اینکارو بکنید کافیه اون متغییری که با اون آبجکت در ارتباط هست رو مساوی null قرار بدید و GC رو به صورت دستی با فرا خوانی تابع gc در کلاس System صدا بزنید که البته خود GC به صورت خودکار هم این کارو انجام میده

تابع finalize در جاوا چیست؟

همون طور که گفتم GC همون اول دخل آبجکت رو نمیاره و هر موقع بخواد اون از حافظه پاک کنه تابع finalize رو صدا میزنه و شما می تونی این متد رو توی یه کلاس override کنید و بفهمید کی از بین رفته. اینم بگم این متد باعث از بین رفتن آبجکت در مموری نمیشه و فقط مثل یه event عمل میکنه پس فکر اینکه با reflection این متدو صدا بزنید و اون شی رو حذف کنید از ذهنتون بیرون کنید


با وجود GC در جاوا دیگه نباید نگران مموری باشیم؟

سخت در اشتباهید، فرض کنید شما برنامه ی توییتر رو نوشتید توی این برنامه داخل پروفایل افراد باید عکس ارسال کننده هر پست در حافظه لود بشه و در Image View مورد نظر نمایش داده بشه. نکته ای که اینجا هست اینه که ما توی پروفایل افراد عموما ارسال کننده خود شخصه و یک عکس باید در چند Image View به نمایش در بیاد. نکاتی که در اینجا باید رعایت بشه عبارت است از:

  1. عکسی که لود میشه داخل حافظه به اندازه ی View تارگت باید کوچیک شه تا کمترین حجم ممکن در حافظه رو داشته باشه
  2. یک عکس رو نباید دو بار در حافظه لود کرد

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

مورد دیگه ای که باید بهش اشاره کنم فیلد های static هست که مستقیم به یه GC Root مرتبط میشن پس سعی کنید هر شی ای رو static نکنید و اگر می کنید بعد اینکه کارتون باهاش تموم شد null کنیدش

رفرنس ها:

GC Roots
Understanding Java Garbage Collection
When does Java calls Garbage Collector



gcjavagarbage collectiongarbage collectorheap
شاید از این پست‌ها خوشتان بیاید