نشت حافظه (Memory Leak) چیست؟

نشت حافظه چیست؟ راه های جلوگیری از Memory Leak

می‌توانید خلاصه‌ای کوتاه از محتوای مقاله را با استفاده از هوش مصنوعی دریافت نمایید.

فهرست مطالب

هر برنامه‌ای برای اجرا به منابعی مانند حافظه RAM نیاز دارد. در حالت استاندارد، زمانی که یک برنامه دیگر به بخشی از حافظه نیاز نداشته باشد، آن بخش باید آزاد شود تا سیستم بتواند دوباره از آن استفاده کند. اما در برخی مواقع به دلیل مشکلات کدنویسی یا مدیریت نادرست منابع، حافظه آزاد نمی‌شود و همچنان در اختیار برنامه باقی می‌ماند. این اتفاق که با نام نشت حافظه (Memory Leak) شناخته می‌شود، می‌تواند به مرور زمان باعث افزایش مصرف منابع، کاهش سرعت برنامه و حتی از کار افتادن سرویس‌ها شود. 

نشت حافظه (Memory Leak) چیست؟

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

حافظه Stack برای مدیریت فراخوانی توابع و نگهداری متغیرهای محلی استفاده می‌شود و به صورت خودکار مدیریت و آزاد می‌شود. در مقابل، حافظه Heap برای تخصیص پویای حافظه به اشیا و داده‌هایی که در طول اجرای برنامه ایجاد می‌شوند، به کار می‌رود. نشت حافظه نیز معمولا در بخش Heap رخ می‌دهد؛ زیرا حافظه‌ای که دیگر مورد نیاز نیست، به‌ درستی آزاد نمی‌شود. برای جلوگیری از این مشکل، راهکارهای مختلفی ارائه شده است که یکی از مهم‌ترین آن‌ها Garbage Collection در زبان‌های برنامه نویسی مدرن است. این ساز و کار به‌ طور خودکار حافظه اشیایی را که دیگر قابل دسترسی یا مورد استفاده نیستند، شناسایی و آزاد می‌کند.

از دلایل اصلی Memory Leak، مشکلات کدنویسی است. برای مثال به کد جاوااسکریپت زیر دقت کنید. 

کد نشت حافظه

در این کد آرایه leakedData به داده‌های قبلی ارجاع می‌شود و به همین دلیل Garbage Collector نمی‌تواند این داده‌ها و حافظه را آزاد کند. این دلیلی است که باعث نشت حافظه یا Memory Leak می‌شود. 

چرا باید از نشت حافظه جلوگیری کرد؟ 

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

  • مصرف منابع: فرض کنید که هاست شما 10 گیگابایت RAM دارد که 8 گیگابایت آن در حال مصرف است. از آنجایی که حافظه کاهش پیدا کرده سیستم از هارد استفاده می‌کند که باعث می‌شود مصرف CPU نیز افزایش پیدا کند. 
  • افزایش تاخیر: وقتی رم حافظه کافی ندارد، سرور شروع به استفاده از هارد می‌کند و از آنجایی که هارد سرعت کمتری نسبت به رم دارد، عملکرد سیستم بسیار کند می‌شود.
  • از کار افتادن سیستم: مشکل به استفاده از هارد و CPU ختم نمی‌شود. اگر نشت حافظه طولانی مدت باشد، سیستم عامل دیگر توانایی پاسخ به نیازهای سیستم را نخواهد داشت و سرور از کار خواهد افتاد. 

دلایل نشت حافظه

Memory Leak از کد برنامه ناشی می‌شود که در زبان‌های مختلف، به شکل‌های مختلفی رخ می‌دهد. اما باید گفت که به طور کلی چند الگوی مشترک در بین این موارد وجود دارد. 

  • Forgotten Event Listeners: به عنوان یک برنامه نویس JavaScript ممکن است زمانی پیش بیاید که Event Listener را به یک عنصر متصل کنید و در نهایت این عنصر را پاک کنید، اما قبل از پاک کردن فراموش کنید که Listener را پاک کنید. در نتیجه Listener و متغیرهای مربوطه در حافظه باقی می‌مانند و باعث نشت حافظه می‌شوند. 
  • Static Collections: دومین موضوعی که برنامه نویس‌ها فراموش می‌کنند و آن را جدی نمی‌گیرند، متغیرهای Static هستند. این متغیرها تا آخر عمر در برنامه باقی می‌مانند و اگر شما بدون پاک سازی، اشیا را به Static اضافه کنید، این مجموعه بسیار بزرگ می‌شود. در آخر با بزرگ شدن این لیست، امکان نشت حافظه نیز بیشتر می‌شود.
  • Circular References: درست است که زبان‌های مدرن، برنامه نویسی را آسان‌تر کرده‌اند، اما چالش‌هایی هم به همراه دارند که با توجه به آنها شما یک برنامه نویس حرفه‌ای خواهید شد. مثلا یکی از دلایل نشت حافظه، ارجاع‌های بلند مدت هستند که چرخه‌های ارجاع را قابل دسترسی نگه می‌دارند و نمی‌گذارند آنها جمع آوری شوند. 
  • Unclosed Resources: اگر فراموش کنید که فایل‌ها، اتصال‌های دیتابیس یا حتی Socketها را ببندید، انتظار نشت حافظه و منابع را داشته باشید. 

راه‌های تشخیص نشت حافظه

  • اگر بازدید سایت شما کم بود، اما رم مصرف زیادی داشت، باید به نشت حافظه شک کرد. 
  • اگر مصرف CPU افزایش یافت و سایت کندتر از همیشه بود، باز هم می‌تواند مشکل از Memory Leak باشد.
  • کد سایت و برنامه را به دقت بررسی کنید و قسمت‌هایی که در آن تغییر ایجاد شده اما کاربردی ندارند، Event Listenerها اضافه هستند اما حذف نشده‌اند، Timerها یا Intervalها در پس زمینه در حال اجرا هستند و… را اصلاح کنید. 
  • زبان‌های برنامه نویسی، ابزارهایی برای کمک به شناسایی نشت حافظه دارند که می‌توانید از آنها برای اصلاح کد استفاده کنید.
  • ابزارهای مانیتورینگ حافظه نیز وجود دارند که مصرف منابع حافظه را بررسی می‌کنند و در صورت مشاهده مشکل به شما اطلاع می‌دهند. برای هاست‌ها استفاده از این مانیتورینگ‌ها می‌تواند جلوی بروز مشکلات بزرگ را بگیرد. 

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

OOM Killer چیست و چرا رخ می‌دهد؟

وقتی حافظه رم (RAM) سرور کاملا پر می‌شود و هیچ فضای خالی باقی نمی‌ماند، سیستم عامل برای جلوگیری از کرش کردن و از کار افتادن کامل سیستم، مکانیزمی به نام OOM Killer را اجرا می‌کند. در این فرایند، پردازش‌هایی که حافظه زیادی مصرف می‌کنند متوقف (Kill) می‌شوند تا فضای رم آزاد شود. این کار بر اساس الگوریتم‌های مشخصی انجام می‌گیرد؛ به عنوان مثال، پردازش‌های حیاتی سیستم عامل هرگز متوقف نمی‌شوند و در عوض، پردازش‌های کم اهمیت‌تر یا پرمصرف‌تر Kill می‌شوند.

راهکارهای پویان آی تی برای مقابله با خطای OOM

پویان آی تی چند روش موثر برای جلوگیری از متوقف شدن ناگهانی سرویس‌ها به کار می‌گیرد:

  • افزایش فضای Swap: در قدم اول، فضای Swap را در سرورها بیشتر در نظر می‌گیریم. در این شرایط، اگر به هر دلیلی رم سرور پر شود، OOM Killer فعال نمی‌شود؛ بلکه داده‌های اضافی به هارد دیسک (فضای Swap) منتقل می‌شوند. هر چند این موضوع ممکن است باعث کمی افت سرعت شود، اما از متوقف شدن پردازش‌ها به طور کامل جلوگیری می‌کند.
  • قفل کردن پردازش‌های حیاتی در رم: برای جلوگیری از کندی بیش از حد ناشی از Swap، پردازش‌های مهم و دیتابیس را در رم قفل (Lock) می‌کنیم. این کار باعث می‌شود تا حتی در شرایط Memory Leak و درگیر شدن هارد دیسک، سرویس‌های حیاتی همچنان روی رم اصلی باقی بمانند و افت عملکرد نداشته باشند.

از آنجا که سرورهای ما بسیار قدرتمند بوده و از ظرفیت بالای رم برخوردارند، احتمال بروز مشکل کمبود منابع از سمت سرور به شدت کاهش می‌یابد. همچنین، در سیستم عامل کلود لینوکس (CloudLinux) قابلیتی به نام LVE وجود دارد که وضعیت رم را بررسی کرده و اطلاعات دقیقی درباره میزان بازدید سایت و مصرف رم به کاربر ارائه می‌دهد. اگر بازدیدهای یک سایت کم باشد اما مصرف رم بسیار بالایی داشته باشد، این موضوع نشان دهنده وقوع نشت حافظه در کدهای آن سایت است. برای خریداری یا کسب اطلاعات بیشتر در مورد میزبانی وب، می‌توانید با پشتیبانی ما در ارتباط باشید. 

آیا در صورت بروز نشت حافظه، سایر سایت‌ها نیز دچار مشکل می‌شوند؟

ما به عنوان ارائه دهنده خدمات هاستینگ، امکان دسترسی و اصلاح کدهای کاربران را برای رفع مشکل نشت حافظه نداریم؛ اما اگر متوجه مصرف بیش از حد و غیر طبیعی رم شویم، اقدامات کنترلی خاصی را اعمال می‌کنیم. به عنوان مثال، پردازش‌های حیاتی مانند دیتابیس را روی رم اصلی حفظ کرده و بار پردازشی مازاد کاربر را به فضای Swap منتقل می‌کنیم.

علاوه بر این، از آنجایی که در پویان آی تی به هیچ وجه سیاست Oversell (فروش بیش از حد ظرفیت سرور) انجام نمی‌شود، حتی در صورت بروز نشت حافظه توسط یک کاربر، منابع کل سرور درگیر نشده و سایر کاربران با افت کیفیت یا قطعی مواجه نخواهند شد. همچنین، استفاده از قابلیت LVE (در سیستم عامل کلودلینوکس) دقیقا جلوی همین مشکل را می‌گیرد؛ این فناوری منابع هر کاربر را به صورت اختصاصی ایزوله می‌کند تا مصرف بالای یک سایت، تاثیری روی سایت‌های دیگر نگذارد.

در نهایت، اگر در موارد بسیار نادر، مصرف رم کل سرور به شدت بالا برود، با کاهش موقت میزان کش سرور (Server Cache) فضا را مدیریت و پایدار می‌کنیم.

راه‌های جلوگیری از نشت حافظه

  • قابلیتی در بیشتر زبان‌های برنامه نویسی وجود دارد با نام Garbage Collection. این قابلیت به طور خودکار حافظه‌ای که کاربرد ندارد را آزاد می‌کند. 
  • ابزارهایی وجود دارد برای Garbage Collection که کد برنامه را تست می‌کنند تا نشت حافظه در مراحل ابتدایی پیدا شود. 
  • بهترین راه نوشتن کد مرتب و تمیز است تا بعدها دچار مشکل نشت حافظه نشود.
  • بهبود مصرف منابع سرور هم می‌تواند در این موضوع تاثیرگذار باشد که روش‌های مختلفی دارد.

در نهایت: Oversell چه ارتباطی با نشت حافظه دارد؟

نشت حافظه (Memory Leak) زمانی رخ می‌دهد که یک برنامه یا سایت، حافظه‌ای را که دیگر به آن نیاز ندارد همچنان در اختیار خود نگه می‌دارد و اجازه آزاد شدن آن را نمی‌دهد. در نتیجه، با گذشت زمان میزان مصرف RAM افزایش پیدا می‌کند و منابع سرور کاهش می‌یابد. اگر این مشکل ادامه پیدا کند، می‌تواند باعث کند شدن برنامه، افزایش مصرف CPU، استفاده بیش از حد از Swap، ایجاد خطاهای مختلف و حتی توقف سرویس شود. نشت حافظه معمولا به دلیل مشکلات کدنویسی مانند حذف نکردن Event Listenerها، نگه داشتن ارجاع‌های غیرضروری، استفاده نادرست از متغیرهای Static یا نبستن منابعی مانند فایل‌ها و اتصال‌های دیتابیس ایجاد می‌شود.

سوالات متداول

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

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

منابع

  • https://middleware.io/blog/memory-leaks/
  • https://odown.com/blog/memory-leaks/

به این مقاله امتیاز دهید!

میانگین امتیاز 0 / 5. تعداد رأی ها : 0

هنوز هیچ رأیی داده نشده. اولین نفر باشید!

و در ادامه بخوانید

اولین دیدگاه را اضافه کنید.

    برچسب ها

    برنامه نویسی سرور رم