Memory Leak یا کمبود حافظه چیست ؟

سلام دوستان عزیز در این سری از آموزش های برنامه نویسی اندروید به بررسی Memory Leak یا کمبود حافظه می پردازیم در ادامه با همراه باشید.
همانطور که اسمش بروی آن است Memory Leak به معنی کمبود حافظه است و در کل هشت حالت وجود دارد که کمبود حافظه اتفاق می افتد. یکی از فواید garbage-collecting-language (زبان جمع آوری زباله) مانند جاوا که به برای توسعه دهندگان به صراحت مدیتریت حافظه اختصاص داده شده ( allocated memory ) را فراهم می کند. علت این کار احتمالا کاهش خطاها (Crash شدن برنامه ) بوده است. اما حافظه به صورت منطقی می تواند leak شود یعنی احتمال ایجاد کمبود حافظه توسط کدهای منطقی جاوا وجود دارد. در نهایت این به این معنی است که ممکن است اپلیکیشن های اندروید هنوز مستعد پذیرش برای هرز دادن حافظه غیر قابل لازم ( unnecessary memory )  و  سبب ایجاد خطای out-of-memory ( خارج از حافظه ) یا oom می شود.خداروشکر هر اکتیویتی همانطور که در پست قبلی مربوط به اکتیویتی به آن اشاره کردیم (سرچ کنید در سایت هست) یک Lifecycle یا چرخه زندگی داره که مهمترینش برای ما onDestroy هست همانطور که توضیح داده بودیم این متد زمانی که چرخه زندگی یک اکتیویتی به پایان می رسد باید اجرا شود.حال به هشت دلیل از Memory Leak می پردازیم

1-Static Activities یا اکتیویتی های ایستا

راحت ترین راه برای memory leak تعریف یک نوع متغیر از نوع static درون همان اکتیوتی است و سپس یک نمونه (instance) از آن را اجرا کنیم ! در زیر یک نمونه از آن را می بینید.

الان نوع متغیر static قرار نگرفته است اما چون در اکتویتی است از نوع static در نظر گرفته شده است . و مقدار this (که خود اکتیویتی است) درون متغیر activity قرار گرفته است (مثل این می ماند که شما یک کار را مداوم انجام دهید) زمانی که آن را اجرا کنید با خطای زیر مواجه می شوید.

 

2-Static Views یا View های ایستا

اگر به طور مکرر و زیاد بخواهیم مقدار id (منظور پیدا کردن id و ریختن آن در یک متغیر البته اینجا از متغیر خود آن استفاده نمی کنیم بلکه از View استفاده کردیم) را درون متغیر از نوع View بریزیم هم سبب ایجاد خطای Memory Leak می شویم همانند مثال زیر

با اجرای کد بالا خطای زیر برای شما نمایان می شود (به طور معمول برنامه force Close می دهد شما بخش Android Monitor را نگاه کنید)

 

3- Inner Classes یا کلاس داخلی

اگر کلاس داخلی ایجاد کنیم سپس درون آن کلاس داخلی یک مثالی از همان کلاس ایجاد کنیم سبب Memory Leak می شود همانند زیر

در بالا کلاس ایجاد شده سپس یک نمونه (instance) از همان کلاس در خودش ایجاد شده.
با اجرا به خطای زیر برخورد خواهید کرد

 

4-Anonymous Classes یا کلاس های ناشناس

اگر ما یک کلاسی درست کنیم که به طور مثال کار AsyncTask در آن وجود داشته و درون این کلاس کاری باشید که هیچ وقت به اتمام نرسد (یک حلقه بی پایان) سبب memory Leak می شود
همانند زیر

همانطور که میبیند در Async در قسمت doInbakground یک while (حلقه بی پایان) تعریف شده است.
و با خطای زیر در صورت اجرا مواجه می شوید.

 

5-Handlers یا دستیار ها

همانند قبلی اگر درون PostDelay (یک مقدار زمانی برای تاخیر است) یک حلقه اجرا شود سبب خطای Memory leak می شود.
کد زیر را نگاه کنید

از آنجایی که هیچ مقداری برای handleMessage ارسال نمی شود handler هیمنطور صبر می کند یعنی در بخش postDelayed می ماند و دیگر به خاطر while بیرون نمی آید.
سپس خطای زیر را خواهید دید.

 

6-Threads یا تردها

ترد هم همانند قبلی اگر درون آن یک حلقه بی انتها وجود داشته باشد خطا را باز خواهیم دید.
کد زیر را تست کنید.

و شکل زیر خطا را برای شما توصیف می کند.

 

 7-TimerTask یا کار تایمر

بازم هم همانند Thread به مثال توجه کنید

فقط شکل خطا متفاوت است.

 
 

8-Sensor Manager یا مدیتریت سنوسر ها

 
زمانی که ما یک سرویسی داریم که در هر لحظه توسط اون سرویس یک دیتای خاص بین اکتیویتی ها Broadcast می شود اگر این کار در هر ثانیه انجام شود به علت این که هم در background است و هم این سرویس در هر ثانیه اجرا می شود سبب Memory Leak می شود.

ممکن است نتوانید کد بالا را تست کنید زیر به یک سرویس نیاز دارد
و خطای نمایش داده شد برابر با زیر می شود.

 
همانطور که دید به چه راحتی ممکن است خطای memory Leak رخ دهد ما تنها 8 تا از عمده آنها را بررسی کردیم.
 
موفق باشید.

مطالعه بیشتر