مموری لیک، کابوس هر برنامه نویس! (قسمت اول)

یک عدد لیک در دنیای واقعی :)
یک عدد لیک در دنیای واقعی :)

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

خب به سلامتی نسخه بتا رو تموم کردیم و همه چی به خوبی و خوشی در محیط دولوپ و تست کار میکنه و مشکلی نداریم وقتشه بزنیم رو پروداکشن و قراره بترکونیم..!

این ها خیالات خام یک برنامه نویس هست که برای بار اول میخواهد پروداکشن را تجربه کند..! معمولا پروداکشن خطرناک تر از آن چیزی هست که در ظاهر نشان میدهد. برای برنامه ای که مموری لیک دارد، در بهترین حالت اگر در اولین اجرا خطایی رخ ندهد به مرور زمان باعث میشود مموری (RAM) سرور را پر کند.

در این مقاله قصد دارم راه هایی که برای حل مشکل مموری لیک در برنامه نود جی اس انجام دادیم را معرفی کنم.




مموری لیک چیست؟

مموری لیک به حالتی از پروسس در حال اجرا گفته میشود که به مرور زمان مموری بیشتری را اشغال میکند و این عمل تا زمانی ادامه خواهد داشت که به اندازه مقدار پارامتر --max-old-space-size برسد، در صورتی که از ابزاری برای مدیریت پروسس هایتان همانند pm2 یا forever استفاده کنید، پروسس شما را ریستارت خواهد کرد (هر ریستارت برابر یک مشتری کمتر و یک مشتری ناراضی)

سوال: پروسس من، رم بسیار بالایی اشغال کرده هست، اما در یک مقدار ثابت در بازه زمانی بسیار طولانی قرار گرفته، آیا برنامه من نیز دارای مموری لیک هست؟ خیر!

شناسایی مموری لیک

ماژول next-memwatch : شاید اولین نتیجه ای که گوگل برای شما پیشنهاد خواهد کرد این ماژول هست. بهترین ماژولی که بتوان گفت برنامه یا پروسس ما دارای مموری لیک هست یا نه next-memwatch هست، برای استفاده از این ماژول کافیست مراحل زیر را انجام دهید:

اضافه کردن ماژول به برنامه

const memwatch = require('memwatch-next');

و گوش دادن به رویداد نشت (ترجمه بعضی کلمات تخصصی انگلیسی به فارسی همانند کشیدن ناخن روی تخته سیاه هست..)

memwatch.on('leak', (info) => {
  console.error('Memory leak detected:\n', info);
});

خب کافیست برنامه تان را استارت کنید در صورتی که پیام زیر را در خروجی مشاهده کردید، تبریک میگویم، بدبخت شدید برنامه شما مموری لیک دارد (مزاح کردم زیاد هم بدبخت نشدید)

Memory leak detected:
{
  growth: 14280616,
  reason: 'heap growth over 5 consecutive GCs (3s) - -2147483648 bytes/hr'
}

هر زمانی که برنامه شما مموری لیک داشته باشد رویداد نشت(leak) اجرا خواهد شد.


خب تا اینجا فهمیدیم که برنامه ما مموری لیک دارد ولی چطور میتوان این مشکل بزرگ را حل کرد. در قسمت دوم قرار هست باهم از ابزاری هایی استفاده کنیم که این معضل را به طور کلی ریشه کن کنیم. پس با من همراه باشید.