هر برنامه نویسی باید بدونه حافظه heap و stack چیه. اماپیچیدگی این مطلب برای برنامه نویسهای تازه کار به قدریه که وقتی این موضوع رو سرچ میکنن و مطالب موجود رو میخونن؛ بیشتر گیج میشن. این میشه که از کنار این موضوع میگذرن و با خودشون میگن: “اگه بعدا نیازش داشتم میرم سراغش”. راستش خود من هم اون روزای اول حسابی بین این دوتا گیج بودم. به همین دلیل یه جلسه این دوره رو به این مفهوم اختصاص دادم. امروز میخوام هیپ و استک رو ساده ساده یادتون بدم. تا انتهای این مقاله همراه من باشید.
قبل از هر چیز Garbage Collector!!!
قبل از اینکه بگیم حافظه heap و stack چی هستن و چطور کار میکنن، باید با Garbage Collector آشنا بشیم. ایشون (یعنی Garbage Collector) وظیفه مهمی در دنیای نرم افزار دارن. ترجمه فارسیِ اسمش به معنی “زباله روب حافظه” است. و شغل شریفش هم همینه که هروقت قسمتی از حافظه کامپیوتر بدون اینکه واقعا نیاز باشه اشغال شده باشه، ایشون فضای اشغال شده رو پاکسازی و حافظه مورد نظر رو آزاد میکنه.
به این ترتیب از اشغال بیش از حد و بدون دلیل حافظه جلوگیری کرده و کمک میکنه با خطای سر ریز حافظه (تموم شدن حافظه مجاز) مواجه نشیم. درصورتی که حافظه مجاز برای یک برنامه حین اجرا تموم بشه برنامه Crash میکنه و اجرا نمیشه. به همین دلیل یه برنامه نویس خوب کسیه که عاقلانه و درست از متغیرها استفاده کنه و هر وقت کارش با متغیری تمام شد حذفش کنه. اینم بگم که جناب Garbage Collector هر 255 میلی ثانیه یکبار حافظه رو چک کرده و فضاهای بی استفاده رو آزاد میکنه.
حالا نوبت Reference Type و Value Type هست:
یکی دیگه از مفاهیمی که باید باهاش آشنا بشید Reference Type و Value Type هست. وقتی شما یه متغیر معمولی میسازید مثلا یه متغیر از نوع عدد صحیح میسازید و مقدار داخلش رو 2 قرار میدید، در حال تعریف یک داده Value Type هستید. یعنی برای ذخیره این متغیر در حافظه، به اینصورت عمل میشه که هرجا متغیر شما هست، مقدارش هم همون جاست. اگه مفهموم متغیر رو یادت نیست، توی جلسات قبلی درباره متغیر صحبت کردیم.
اما نوع دیگهای از متغیرها یعنی Reference Type ها هم وجود دارن. وقتی شما متغیری میسازید که یک مقدار مشخص نداره (مثلا ذخیره اطلاعات یک دانشجو) متغیر شما یک Reference Type هست. همونطور که میدونید دانشجو اطلاعات مختلفی مثل اسم، تلفن، آدرس و… داره که باید برای ذخیره اطلاعاتش یکی شی از کلاس دانشجو بسازیم. از اونجایی که فعلا نیاز نیست وارد پیچیدگیهای شی گرایی و کلاسها بشید که خودش یه دنیاست، بدونید که برای ذخیره اطلاعاتی که یک مقدار قطعی و مشخص ندارن باید از کلاسها استفاده کنیم. توی جلسات بعدی درباره کلاسها حرف میزنیم.
حافظه heap و stack بدون شناخت جناب Pointer صفا نداره:
سومین مفهوم مهمی که باید بلد باشید آقای پوینتره (به اسمش میاد مذکر باشه). وظیفه پوینتر اینه که آدرس قرار گیری دادهها در قسمتهای مختلف حافظه رو ذخیره کنه. برای مثال اگه به مثال تعریف دانشجو برگردیم؛ ممکنه اسم دانشجو توی یه قسمت ذخیره بشه و اطلاعات درسهاش توی یه قسمت دیگه. بنابراین ما به متغیری نیاز داریم که آدرسها رو برای ما نگهداری کنه و اون هم کار آقای پوینتره.
اینو یادتون باشه که هروقت از یک Reference Type استفاده کنید قطعا پای یک پوینتر هم در میونه. به همین دلیل رفرنس تایپ و وَلیو تایپ 2 تا فرق مهم با هم دارن.
- رفرنس تایپ نسبت به وَلیو تایپ به مقدار بیشتری فضا برای ذخیره نیاز داره. چون پوینتر هم باید یه جایی ذخیره بشه.
- سرعت رفرنس تایپها نسبت به وَلیو تایپ ها کمتره چون باید آدرسها رو دنبال کنه.
حالا بریم سراغ حافظه heap و stack:
وقتی یک برنامه نرم افزاری اجرا میشه، کامپیوتر 2 تا حافظه در اختیارش میذاره که یکی ثابته و یکی متغیر. حافظه ثابت توسط سیستم عامل مشخص و تا پایان اجرای برنامه بلوکه میشه که بهش میگن Static Memory یا حافظه stack. و حافظه متغیر هم همون حافظه heap هست که به صورت دستی توسط برنامه نویس مدیریت میشه.
معمولا روال کار اینه که مقدار value type ها در حافظه استک و مقدار reference type ها در حافظه هیپ ذخیره میشه. ساختار حافظه استک مثل یک لیست یک طرفه است که دسترسی بهش به صورت ترتیبی انجام میشه. مثلا اگه 10 تا بشقاب رو روی هم بچنید، اولین بشقابی که میتونید بردارید، آخرین بشقابیه که قبلا روی بشقابهای قبلی گذاشتید. اما ساختار هیپ هیچ ترتیبی نداره و هر قسمت حافظه رو با داشتن یک آدرس، در دسترس قرار میده (که وظیفه آقای پوینتره).
در آینده درباره ساختمانهای داده و ساختار هیپ و استک بیشتر صحبت میکنیم. نکته مهمی که میخوام بگم اینه که این دو، دوتا ساختمان داده هستند که چون این بخش از حافظه با این دو ساختمان داده در دسترس قرار میگیره بهشون میگن حافظه heap و stack. پس با هم قاطیشون نکنید.
مدیریت حافظه استک توسط خود سیستم عامل انجام میشه اما مدیریت هیپ با برنامه نویس و جناب Garbage Collector هست. پس خیلی مهمه که درست از رفرنس تایپها استفاده کنید. شی های بی استفاده و زیاد از حد نسازید. بعد از اینکه کارتون با یک متغیر تموم شد حذفش کنید و… .
امیدوارم این مطلب براتون مفید بوده باشه و دیگه ابهامی درباره حافظه heap و stack نداشته باشید.