موضوع مقاله: نشت حافظه | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # نشت حافظه | مقدمه: نشت حافظه (در علوم کامپیوتر) زمانی اتفاق می‌افتد که یک برنامه، حافظه‌ای از سیستم عامل دریافت کند ولی قادر به آزاد کردن و برگرداندن آن نباشد. | ## بخش 1: نشت حافظه | کمبود حافظه خود نشانه‌ای بر وجود مشکلات دیگری (در ادامه می‌بینیم) است و معمولاً تنها با اشکال زدایی کد منبع توسط برنامه‌نویس اصلاح می‌شود. با این وجود بسیاری از مردم کمبود حافظه را به هر افزایش ناخواسته فضای مصرف شده نسبت می‌دهند، هرچند که این تعریف کاملاً درست نیست. نتیجه کمبود حافظه با کاهش دادن مقدار فضای آزاد می‌تواند باعث کاهش کارایی سیستم گردد. سرانجام در بدترین حالت بیشتر فضای موجود اشغال می‌شود که این امر می‌تواند موجب از کار افتادن کل یا بخشی از سیستم و سخت‌افزار، بروز مشکل در نرم‌افزارها یا حتی تأخیر غیرقابل قبولی در سیستمی که منجر به تریشینک می‌شود، بشود. در سیستم عامل‌های جدید، حافظه مورد استفاده نرم‌افزارها پس از خروج آن‌ها آزاد می‌گردد؛ یعنی کمبود حافظه در برنامه‌هایی که برای مدت کوتاهی اجرا می‌شوند خیلی جدی و قابل احساس نیستند. بعضی از مواردی که می تواند در کمبود حافظه جدی باشند: زمانی که برنامه‌ای برای مدتی طولانی اجرا می‌گردد و در طول زمان فضای بیشتری مصرف می‌کند، مانند برنامه‌هایی که در پس زمینه سرورها مخصوصاً در سامانه‌های توکار که برای سال‌ها در حالت اجرا باقی می‌مانند. زمانی که حافظه‌ای به‌طور متناوب از سیستم گرفته می‌شود، مثلاً رمانی که فریم‌های یک بازی کامپیوتری یا فیلم را تحلیل می‌کنیم. زمانی که برنامه قادر به درخواست حافظه (مثلاً حافظه به اشتراک گذاشته شده) است ولی حافظه حتی پس از خروج از برنامه آزاد نمی‌شوند. زمانی که سیستم عامل پس از بسته شدن برنامه به‌طور خودکار حافظه‌های اخذ شده را آزاد نکند (و فقط پس از راه اندازی مجدد آزاد گردد)، مانند آمیگا او اِس. مثالی از کمبود حافظه در مثال بیان شده (در ذیل) که توسط شبه‌کد نوشته شده‌است قصد داریم نشان دهیم که کمبود حافظه چگونه می‌تواند به وجود آید و چگونه موثر باشد(بدون نیاز به هیچ گونه دانش برنامه‌نویسی). این برنامه قسمتی از یک نرم‌افزار ساده‌ای است که به منظور کنترل یک آسانسور نوشته شده‌است. این قسمت از برنامه زمانی که هر شخص داخل آسانسور دکمه مربوط به طبقه همکف فشار دهد، اجرا می‌شود. زمانی که یک دکمه فشار داده شد فضایی برای ذخیره شماره طبقه اخذ کن شماره طبقه را در حافظه گرفته شده ذخیره کن آیا هم‌اکنون در طبقه همکف هستیم؟ اگر آره:پس هیچ کاری انجام نده: تمام در غیر اینصورت: منتظر بایست تا آسانسور آماده کار شود به طبقه مطلوب برو فضای استفاده شده برای ذخیره شماره طبقه را آزاد کن در این مثال کمبود حافظه زمانی اتفاق می‌افتد که آسانسور در طبقه درخواست شده باشد. مردم معمولاً کلید مربوط به طبقه‌ای را که در آن هستند فشار نمی‌دهند، در هر حال ممکن است که آسانسور فضای گسسته کافی برای صد یا هزار بار تکرار این پیش آمد را داشته باشد. این کار می‌تواند ماه‌ها یا سال‌ها طول بکشد، پس این مشکل از طریق آزمایش قابل تشخیص نیست. نتیجه می‌تواند ناخوشایند باشد: زمانی که حافظه آزاد بسیار کم شود آسانسور نمی‌تواند پاسخی به درخواستها بدهد. اگر قسمت‌های دیگر برنامه نیازی به فضا داشته یاشد مثلاً قسمتی که برای باز یا بسته کردن آسانسور نوشته شده‌است از آنجایی که دیگر نرم‌افزار قادر به باز کردن در نمی‌باشد سبب گیر کردن فرد در آسانسور شود. اگر منبع را دوباره وصل کنیم برنامه از اول اجرا می‌شود و فضای حافظه آزاد می‌شود ولی دوباره کم‌کم می‌تواند سبب کمبود حافظه گردد و سرانجام سبب لطمه به اجرای صحیح سیستم گردد. موضوع برنامه‌نویسی کمبود حافظه یک خطای معمول در برنامه‌نویسی محسوب می‌شود، مخصوصاً زمانی که از زبانی که در داخل خودش زباله روبی خودکار ندارد استفاده می‌کنیم مانند سی++ یا سی. معمولاً به این علت کمبود حافظه رخ می‌دهد که حافظه پویا به حافظه غیرقابل دسترس تبدیل می‌شود. رواج مشکل کمبود حافظه سبب تولید تعداد زیادی ابزار اشکال‌زدایی که قابلیت تشخیص حافظه غیرقابل دسترس را داشتند شد. | ## بخش 2: نشت حافظه | قابلیت زباله روبی «محافظه کار» را می‌توان به صورت یک ویژگی داخلی به هر زبانی که آن را ندارد اضافه نمود. زباله روب محافظه کار قابلیت پیدا کردن و آزادسازی بیشتر حافظه‌های غیرقابل دسترس را دارند نه همه. مدیریت حافظه می‌تواند حافظه‌های غیرقابل دسترس را بازیابی کند، (نمی‌تواند حافظه‌هایی که در در دسترس هستند را آزاد کند) که این امر ذاتاً مفید است. مدیریت حافظه‌های مدرن، تکنونوژی به برنامه نویسان ارائه کردند تا با کمک آن بتوانند براساس تفاوت سطحهای مفید بودن نشانه‌گذاری کنند (تفاوت در سطحهای قابل دسترس بودن). یک شئ را زمانی در دسترس قوی می‌نامیم که توسط یک ارجاع قوی در دسترس باشد یا توسط زنجیره‌ای از ارجاع‌های قوی در دسترس باشد. (زمانی یک ارجاع را ارجاع قوی می‌نامیم که بر خلاف ارجاع ضعیف از زباله روب شدن خودداری کند). بدین منظور توسعه دهندگان مسئول پاک‌سازی ارجاع‌ها پس از استفاده از آن‌ها می‌باشند که این امر معمولاً با مقدار دهی تهی به ارجاع‌هایی که احتیاج ندارند صورت می‌گیرد و اگر لازم باشد با پاک کردن هر گوش دهندهٔ رخدادی که شامل ارجاع قوی به شئ مورد نظر باشد صورت می‌گیرد. مدیریت حافظه خودکار برای توسعه دهندگان بسیار مناسب است، زیرا آن‌ها احتیاجی به پیاده‌سازی فرایند آزادسازی حافظه ندارند و هیچ گونه نگرانی برای اینکه آیا حافظه به خوبی آزاد شده‌است یا نه ندارد و دیگر نیازی به تمرکز بر اینکه آیا برای حافظه ارجاعی وجود دارد یا نه ندارند. برای برنامه نویسان دانستن اینکه نیازی به ارجاع ندارند راحتنر از این است که بدانند چه زمانی به حافظه هیچ ارجاعی وجود ندارد. با این وجود مدیریت حافظه خودکار باعت کاهش سرعت اجرا می‌شود و نمی‌تواند همه خطاهایی که منجر به کمبود حافظه می‌شود را حذف کند. بر خلاف زباله روبها، آر اِی آی آی این خوبی را دارد که می‌دانیم که شئ چه زمانی وجود دارد و چه زمانی وجود ندارد. برای مثال اگر شخص مراقب نباشد، ممکن است که با برگرداندن داده‌ای که با خروج از بلوک آزاد می‌گردد به صورت ارجاع، باعث به وجود آمدن اشاره گر آویزان شود. زبان دی از ترکیبی از آر اِی آی آی و زباله روب استفاده می‌کند (استفاده از مخرب خودکار زمانی که شئ به‌طور واضح از بلوک خارج می‌شود و استفاده از زباله روب در غیر این صورت). شمارنده ارجاع و مرجع‌های چرخه‌ای طراحی زوباله روب‌های جدید معمولاً بر اساس در دسترس بودن است (اگر هیج ارجاع قابل استفاده‌ای به آن موجود نیست می‌توان آن را جمع‌آوری کرد). دسته‌ای دیگر از زباله روب‌ها بر اساس شمارنده ارجاع است به این صورت که هر شی مسئول نگه‌داری رد مسیر برای دانستن تعداد ارجاع‌ها به آن است. مشکل این طرح این که نمی‌تواند در مرجع‌های چرخه‌ای (دایره‌ای) به خوبی رفتار کند و به همین دلیل امروزه ما برای پذیرفتن هزینهٔ زیاد سیستم‌های نشانه‌گذاری و زدودن آماده می‌شویم. در این مثال کوچک می‌توان به راحتی مشکل را بر طرف کرد ولی در اکثر مثال‌های واقعی، چرخهٔ اشاره گرها بیش از دو شئ را دربر گرفته و تشخیص آن سخت‌تر است. تأثیرات اگر یک برنامه کمبود حافظه داشته باشد و حافظهٔ مورد استفاده آن به‌طور یکنواخت افزایش یابد، هیچ نشانه سریعی (سریعاً قابل تشخیص باشد) قابل مشاهده نیست. هر سیستم یک نهایت برای حافظه دارد و با دوباره اجرا کردن برنامه به زودی یا پس از مدتی مشکل تکرار می‌شود. اکثر استفاده‌کننده‌های سیستم عامل‌های رو میزی از حافظه اصلی (بر روی میکروچیپ‌های رَم) و هم از حافظه ثانویه (مانند دیسک سخت) استفاده می‌کنند. صفحه‌های فعال برای دسترسی سریع به حافظهٔ اصلی انتقال می‌یابند و صفحه‌های غیرفعال برای صرفه جویی در حافظه به حافظه ثانویه انتقال می‌یابند. زمانی که یک پروسه شروع به مصرف زیاد حافظه می‌کند معمولاً موفق به اخذ حافظه بیشتر و بیشتر می‌شود و باعث فرستادن برنامه‌های دیگر به حافظهٔ ثانویه می‌گردد (که باعث هزینهٔ زیاد و سرعت کم). | ## بخش 3: نشت حافظه | حتی اگر برنامه‌ای که سبب کمبود حافظه شده‌است خاتمه داده شود ممکن است مدت زمانی برای برنامه‌های دیگر طول بکشد تا خود را به حافظه اصلی انتقال دهند و کارایی به حالت عادی خود برسد. زمانی که همهٔ حافظه یک سیستم مصرف شد (زمانی که حافظه مجازی وجود داشته باشد یا فقط حافظه اصلی موجود باشد مانند سیستم‌های جاسازی شده) هر گونه تلاش برای تخصیص حافظه رد می‌شود. این امر سبب می‌شود که برنامه برای خاتمه دادن به خود، شروع به تلاش برای تخصیص حافظه کند یا شروع به تولید قطعه بندی خطا کند. بعضی از برنامه‌ها برای بازیابی از چنین شرایطی طراحی شده‌اند (ممکن است با استفاده از حافظه از قبل رزرو شده). اولین برنامه‌ای با پر شدن حافظه روبه رو می‌شود ممکن است آن برنامه‌ای نباشد که دارای کمبود حافظه است. بعضی از سیستم عامل‌های چند وظیف ای یک روش مخصوص به خود برای برخورد با پر شدن حافظه دارند مانند حذف تصادفی پروسه‌ها (ممکن است بر روی یک پروسه بی گناه صورت بگیرد) یا حذف پروسه‌ای که از بیشترین حافظه استفاده می‌کند (که احتمالاً یکی از پروسه‌هایی بوده که سبب مشکل بوده). بعضی از سیستم عامل‌ها برای هر پروسه یک محدودیت حافظه دارند تا از به زور گرفتن همه حافظه توسط برنامه جلوگیری کند. بدی این ایده این است که سیستم عامل باید گاهی اوقات دوباره تنظیم گردد تا بتواند به برنامه‌هایی که واقعاً نیاز به فضای زیادی دارند فضای کافی در نسبت دهد (مانند برنامه‌های گرافیکی، ویرایش فیلم و محاسبات علمی). کامپیوترهایی که از مدیریت حافظه خبره استفاده نمی‌کنند مانند سیستم‌های جاسازی شده ممکن است در اثر کمبود حافظه ماندگار، از کار متوقف شود. سیستم‌های در دسترس عموم مانند سرویس دهنده‌های وب یا مسیریاب‌ها برای حملات انکار سرویس مستعد هستند در صورتی که حمله‌کننده دنباله از کارهایی که سبب کمبود حافظه می‌شود راکشف کند. دیگر مصرف‌کننده‌های حافظه باید توجه داشته باشیم که افزایش مداوم استفاده از حافظه نمی‌تواند نشان کمبود حافظه باشد؛ مثلاً بعضی از برنامه‌ها به‌طور افزایشی مقدار زیادی از اطلاعات را در حافظه ذخیره می‌کنند (شبیه ذخیره گاه). اگر این ذخیره گاه بتواند به مقدار زیادی افزایش یابد باعث ایجاد مشکل می‌گردد که ممکن است در اثر طراحی یا برنامه‌نویسی نا درست به وجود آمده باشد، ولی این امر کمبود حافظه تلقی نمی‌شود زیرا تمام حافظه استفاده شده قابل دسترسی است. در حالتی دیگر ممکن است برنامه‌نویس به‌طور نامعقولی درخواست حافظهٔ زیادی کند چون که برنامه‌نویس در این تصور بوده که حافظه موجود برای آن کار همیشه در دسترس است. برای مثال پردازش گر فایل‌های گرافیکی شروع به خواندن همهٔ فایل و ذخیره آن در حافظه کند، در صورتی که فضای لازم موجود نباشد برنامه در اجرا دچار مشکل می‌شود. کمبود حافظه در اثر نوع خاصی از اشکال در برنامه‌نویسی رخ می‌دهد و در صورتی به منبع کد آن دسترسی نداشته باشیم تنها با دیدن نشانه‌های آن می‌توان حدس زد که شاید بر نامه دارای کمبود حافظه است. در صورتی که به درون برنامه هیچ شناختی نداریم بهتر است از عبارت «افزایش مداوم و ثابت حافظه مورد استفاده» استفاده کنیم. مثالی ساده در زبان سی در این مثال سی ما عمداً با از دست دادن اشاره گر به حافظه تخصیص یافته سبب کمبود حافظه می‌شویم. به این دلیل که تخصیص حافظه بدون ذخیره آدرس آن به‌طور همیشگی ادامه دارد در نهایت باعت به وجود آمدن توقف (مقدار تهی برمی‌گرداند) در اجرا می‌شود در جایی که حافظه پر شده‌است. به این دلیل که آدرس حافظه تخصیص یافته ذخیره نمی‌شود امکال آزاد کردن حافظه‌های تخصیص یافته قبلی وجود ندارد. باید به نکته توجه داشت که سیستم عامل تا زمانی که هیچ داده‌ای بر روی حافظه تخصیص یافته نوشته نشده‌است بین تخصیص حافظه واقعی تأخیر می‌اندازد و برنامه زمانی که آدرس‌های مجازی آن از محدوده خارج می‌شود پایان می‌یابد. | ## جمع‌بندی | (برای هر پروسه بین ۲ تا ۴ گیگا بایت محدود است البته برای سیستم عامل‌های ۶۴ بیتی محدودیت کمتری وجود دارد).