جلسه یازدهم
مقدمه
مدیریت حافظه از مباحث بنیادی در طراحی زبانهای برنامهنویسی است. هر برنامه برای ذخیرهسازی دادهها، اجرای توابع و مدیریت ساختارهای مختلف نیازمند حافظه است. درک نحوهٔ تخصیص، آزادسازی و محدودهٔ اعتبار متغیرها به نوشتن برنامههای کارآمد و قابلاعتماد کمک میکند.
۱) مدیریت حافظه در زبانهای برنامهنویسی
مدیریت حافظه شامل سه بخش اصلی است:
- تخصیص حافظه: ایجاد فضایی برای ذخیره دادهها.
- استفاده از حافظه: خواندن و نوشتن دادهها در طول اجرای برنامه.
- آزادسازی حافظه: بازگرداندن حافظهٔ استفادهشده به سیستم.
روشهای مدیریت حافظه
- مدیریت دستی: برنامهنویس باید حافظه را صریحاً تخصیص و آزاد کند.
- مدیریت خودکار: سیستم یا زبان برنامهنویسی آزادسازی حافظهٔ غیرقابلدسترس را بر عهده دارد (مثلاً با Garbage Collector).
- ترکیبی: برخی زبانها بخشی از مدیریت را خودکار و بخش دیگر را به برنامهنویس واگذار میکنند.
۲) Scope متغیرها
Scope یا «محدودهٔ دسترسی» تعیین میکند که یک متغیر در کدام بخش از برنامه قابل استفاده است.
انواع Scope
- سراسری (Global): متغیرهایی که در تمام بخشهای برنامه قابل دسترسی هستند.
- محلی (Local): متغیرهایی که فقط داخل یک تابع، بلوک یا ساختار خاص معتبرند.
- بلوکمحور (Block Scope): متغیرهایی که فقط داخل یک بلوک تعریفشده معتبرند (در بسیاری از زبانهای جدید).
- تابعمحور (Function Scope): متغیرهایی که فقط در بدنهٔ تابع زندهاند.
اهمیت Scope
- جلوگیری از تداخل نامها
- کمک به ساختاردهی بهتر برنامه
- بهبود امنیت و کنترل بر دادهها
- کاهش احتمال بروز خطا
۳) Lifetime متغیرها
Lifetime یا «دورهٔ حیات» مدتزمانی است که یک متغیر در حافظه وجود دارد و فضای آن اشغال شده است. Lifetime ممکن است با Scope متفاوت باشد.
انواع Lifetime
- خودکار (Automatic): متغیر هنگام ورود به یک بلوک ایجاد شده و هنگام خروج از آن نابود میشود.
- پویا (Dynamic): متغیر توسط برنامهنویس یا سامانه تخصیص داده میشود و تا زمانی که آزاد نشود در حافظه باقی میماند.
- ایستا (Static): متغیر از شروع برنامه تا پایان آن پابرجا میماند.
تفاوت Scope و Lifetime
- Scope «کجاست؟» را مشخص میکند.
- Lifetime «تا کی؟» را مشخص میکند.
گاهی متغیر در Scope نیست اما هنوز در حافظه وجود دارد (مانند برخی دادههای پویا).
۴) حافظهٔ پشته و حافظهٔ heap
زبانها از ساختارهای متفاوتی برای مدیریت حافظه استفاده میکنند.
پشته (Stack)
- مخصوص متغیرهای خودکار و محلی
- سریع و ساختاریافته
- آزادسازی خودکار هنگام خروج از تابع یا بلوک
heap
- مخصوص دادههایی که Lifetime آنها پویاست
- تخصیص و آزادسازی غیرساختاریافته
- نیازمند مدیریت دستی یا مکانیزمهای خودکار مثل Garbage Collection
۵) نقش Garbage Collection
در زبانهایی که مدیریت حافظه خودکار است، GC موارد زیر را انجام میدهد:
- شناسایی دادههایی که دیگر قابل دسترس نیستند
- آزادسازی فضای آنها
- جلوگیری از نشت حافظه
- سادهکردن طراحی برنامه
GC هزینههایی هم دارد، مثل مصرف پردازش و توقفهای مقطعی، اما نوشتن برنامه را سادهتر میکند.
۶) مشکلات رایج در مدیریت حافظه
- نشت حافظه: فراموشی آزادسازی حافظهٔ پویا
- استفاده از حافظهٔ آزادشده: دسترسی به دادههای حذفشده
- سرریز پشته: استفادهٔ بیش از حد از فراخوانیهای تو در تو
- تخصیص ناکارآمد: اشغال فضای زیاد یا تخصیصهای تکراری
۷) جمعبندی
- مدیریت حافظه پایهٔ مهمی در طراحی هر زبان است.
- Scope و Lifetime از مفاهیم کلیدیاند و لزوماً یکسان نیستند.
- حافظهٔ stack و heap نقشهای متفاوتی دارند.
- روشهای خودکار مانند Garbage Collection توسعهٔ نرمافزار را آسانتر کرده اما سربار خود را دارند.
- آشنایی با مدیریت حافظه باعث نوشتن برنامههایی کارآمدتر، ایمنتر و قابل اعتمادتر میشود.