Nima.Sl
Nima.Sl
خواندن ۳ دقیقه·۲ سال پیش

حافظه Heap & Stack به زبان ساده :)


وقتی یک applicationجاوا اجرا میشود دقیقا چه اتفاقی در پشت صحنه می افتد؟ من میخوام در این ویرگول درمورد object ها و heapو stack صحبت کنم.

وقتی شما یک کلاس را تشکیل میدهید بلافاصله یک متد mainساخته میشود. اگر شما روی دکمه run کلیک کنید، 2 عدد memory location ،ایجاد (reserve) میشوند درست بعد از run کردن application. این ها در واقع منابع کامپیوتر شما یا همان stackو heap میباشند.


حافظه Stack

بعد از run کردن برنامه یا application داخل Eclipse داخل stack یک فریم تشکیل میشود به نام تابع اصلی کلاس ما (یا همان متد main):


تمام variable هایی که داخل متد main ایجاد میشوند، local variable یا متغیر محلی نام دارند. پس اگر ما یک متغیر سن را ایجاد کنیم ;int age داخل فریم تابع main یک بخش کوچکی را به خود اختصاص میدهد.


فرض کنید در خط بعدی، یعنی بعد از تعریف متغیر ageیک متد دیگری داخل متد main فراخوانی شده باشد:

public class Car{

public static void main(String[] args){

int age = 15;

doWork();

}

}

که بلافاصله داخل stackیک فضا ذخیره میشود به نام این متد و اگر متغیری به نام weightداشته باشد در داخل آن قرار میگیرد و اگر داخل خود متد () doWork متد دیگری به نام ()doMore فراخوانی شده باشد باز هم در stack یک فضا به آن متد اختصاص داده میشود

public static void doWork(){

int weight;

doMore();

}


بعد از این که متد ;()doMore و همچنین متد ;()doWork به پایان رسیدند از داخل حافظه stack حذف یا به اصطلاح pop میشوند، و اگر به آن ها نیاز باشد و در خطوط بعدی برنامه مجدد فراخوانی شوند، به راحتی مجدد به داخل حافظه stack وارد(push) میشوند:



حافظه Heap

حالا فرض کنید در خط بعدی برنامه ما یک reference variable ایجاد کنیم در متد main:

public class Car{

public static void main(String[] args){

int age = 15;

doWork();

Car myCar;

}

}

متغیر myCarبه یک actual object اشاره میکند. دقت کنید ما فعلا چیزی را assignنکردیم و صرفا یک متغیر تعریف کردیم:


وقتی ما این متغیر جدید را assign کنیم، یعنی وقتی از واژه new استفاده میکنیم، در واقع، داخل حافظه Heapیک object به نام carایجاد میشود که این متغیر myCar به آن اشاره میکند:

public class Car{

public static void main(String[] args){

int age = 15;

doWork();

Car myCar;

myCar = new Car();

}

}

اما باید به این نکته توجه داشت که متغیر myCar مستقیم به car object اشاره نمیکند و به آدرس آن در حافظه که Heap نام دارد اشاره میکند، در واقع متغیر myCar یک memory address، میباشد که assign شده است به آدرس object نه خود object اصلی. ولی در متغیر محلی مثل age وقتی ما عدد 15 را داخل آن قرار دادیم متغیر محلی age خود دیتا اصلی را دریافت کرد در حالی که در reference variableها آدرس یک object به آن ها نسبت داده میشود نه خود object.

وقتی که اجرای این خط از برنامه myCar = new Car(); تمام شد یا object جدیدی ایجاد شد خطی که از متغیر myCar به سمت object اول car اشاره میکند پاک شده و به object جدید اشاره میکند و car object اول توسط Garbage collection بلعیده میشود :)

یک مثال دیگر، فرض کنید یک کلاس ساده car داریم که داخل آن یک instance variable برای اسب بخار ماشین یا همان hp داریم. وقتی 2 عدد object از کلاس car داخل کلاس اصلی ایجاد کنیم یعنی:

Car my2car = new Car();

Car my3car = new Car();

آن متغیر instance variable این بار داخل حافظه Heap به عنوان بخش کوچکی از car object تشکیل میشود:

و داخل حافظه stack هم همانطور که اشاره کرده بودیم 2 متغیر ایجاد میشوند که به آدرس این object ها اشاره میکنند.


ممنون بابت وقتی که گذاشتید :)

معماری نرم افزارstackheapحافظه
شاید از این پست‌ها خوشتان بیاید