در زبان برنامه نویسی جاواجاوا چیست؟ تعریف، معنی و ویژگی های جاوا (java) از 0تا100جاوا یک زبان برنامه نویسی همه منظوره، مبتنی بر کلاس و شی گرا است که برای داشتن وابستگی های پیاده سازی کمتر طراحی شده است، زبان برنامه نویسی جاوا شبیه ++C است، مدیریت حافظهمدیریت حافظه در برنامه نویسی ⚡️ سه سطح مهم در مدیریت حافظهاین مقاله عالی سه سطح مهم در مدیریت حافظه یعنی مدیریت حافظه در سطح سختافزار، مدیریت حافظه در سطح سیستم عامل و مدیریت حافظه در سطح برنامه را معرفی کرده به تخصیص دادن و عدم تخصیص اشیاء یا آبجکتها (Objects) گفته میشود. زبان جاوا به صورت خودکار فرآیند مدیریت حافظه را به وسیله سیستمی با نام زباله روب یا Garbage Collector انجام میدهد؛ برخلاف زبانهایی مانند C++ که در آن تمامی این عملیات به صورت دستی و توسط برنامه نویس انجام میشود.
مدیریت حافظه در زبان جاوا به دو بخش عمده تقسیم میشود:
- ساختار حافظه ماشین مجازی جاوا (JVM Memory Structure)
- عملیات مربوط به Garbage CollectionGarbage Collection(GC) چیست و چگونه کار میکند؟این مقاله عالی بررسی کرده که Garbage Collection(GC) چیست و چگونه کار میکند؟ و مزایای Garbage Collection و انواع روش های Garbage Collection را معرفی کرده
مدیریت حافظه در ساختار JVM
ماشین مجازی جاوا یا Java Virtual Machine، دادههای زیادی را در زمان اجرا (Run Time) درون حوزه هیپدرخت هیپ (heap) چیست؟ آموزش هیپ در ساختمان دادهاین صفحه عالی به آموزش هیپ (heap) در ساختمان داده پرداخته و اعمالی که در هرم قابل انجام است و مزایا و معایب حافظه Heap و مثال کدنویسی از Heap را آورده(Heap) تولید میکند. این حوزه در حین اجرای برنامهها استفاده میشود. در تصویر زیر میتوانید ساختار حافظهای JVM را مشاهده کنید.
در ادامه مقاله به بررسی حوزههای معرفی شده در شکل بالا میپردازیم.
حوزه متدها (Method Area)
حوزه متدها در واقع بخشی از حافظه Heap است که در میان تمامی Threadها به اشتراک گذاشته شدهاند. این حوزه به محض اینکه JVM شروع به کار کرد ساخته میشود. مواردی از قبیل ساختار کلاسها، نام سوپر کلاسها، نام اینترفیسها و سازندهها (Constructors) در این حوزه ذخیره میشوند. به طور کلی JVM اطلاعات زیر را درون حوزه متدها ذخیره میکند:
- ذخیره نوع ها یا Typeها
- اصلاح کنندهها یا Modifier های این Typeها
- نام سوپر کلاس Typeها
- لیستی از نام سوپر اینترفیسها
حوزه هیپ (Heap Area)
همانند حوزه ی متدها، زمانی که JVM شروع به کار میکند، حوزه هیپ ایجاد میشود. به طور خلاصه این حوزه در زبان جاوا آبجکت های واقعی را ذخیره میکند. کنترل کردن حوزه هیپ میتواند در دست کاربران باشد، همچنین اندازه هیپ نیز میتواند ثابت و یا پویا باشد. زمانی که در کدنویسیکدنویسی چیست؟ – کد نویسی یعنی چهاین مقاله عالی به بررسی این پرداخته که کد نویسی چیست و مفهوم کد نویسی را بررسی کرده، همچنین تفاوت کدنویسی و برنامه نویسی و کاربرد های کدنویسی را بررسی کرده از واژه new استفاده میکنید، JVM یک اینترفیس مربوط به آبجکت ایجاد شده در هیپ میسازد در حالی که ارجاع به آن آبجکت در فضای پشتهساختمان داده پشته ⚡️ پشته چیست؟ کاربرد پشته در ساختمان دادهاین مقاله عالی توضیح داده که پشته چیست و کاربرد پشته در ساختمان داده چیست، همچنین نحوه کارکرد پشته، پیاده سازی پشته و عملیات های پشته را معرفی کرده یا استک (Stack) ذخیره میشود. لازم است بدانید تنها یک هیپ به ازای هر فرایند JVM ساخته میشود. زمانی که هیپ پر شد، عملیات زباله روبی شروع میشود و به اصطلاح Garbageها Collect میشوند. به عنوان مثال کد زیر را در نظر بگیرید:
StringBuilder sb= new StringBuilder();
عبارت بالا یک شی از کلاس StringBuilder ایجاد میکند. این آبجکت درون فضای هیپ ذخیره میشود و یک ارجاع به sb نیز درون پشته ایجاد میشود.
هیپ از 5 بخش زیر تشکیل شده است:
- Young Generation
- Survivor Space
- Old Generation
- Permanent Generation
- Code Cache
نوع ارجاع یا Reference Type
یکی از قسمت های مهم هر زبان برنامه نویسیزبان های برنامه نویسی چیست؟این مقاله عالی توضیح داده که زبان های برنامه نویسی چیست؟ و انواع زبان های برنامه نویسی و بهترین زبان برنامه نویسی برای شروع و پردرآمدترین آنها را معرفی کرده، نوع های ارجاعی میباشد. در زبان جاوا، Reference Type از 4 نوع تشکیل شده است:
- نوع قوی (Strong)
- نوع ضعیف (Weak)
- نوع نرم (Soft)
- نوع فانتوم (Phantom)
شاید به این فکر کنید یک ارجاع چرا باید نوع های مختلف داشته باشد؟ هر آبجکت درون هیپ که ارجاعی به آن درون پشته قرار دارد، دارای یکی از این نوعها میباشد. این نوعها روند Garbage Collection تحت شرایط مختلف را مشخص میکنند.
نوع قوی
ساده ترین نوع ارجاع همین نوع است که ما روزمره در کد هایمان استفاده میکنیم. هر آبجکتی که یک ارجاع قوی به آن ایجاد شده باشد، شامل حال Garbage Collection نمیشود. کد زیر که پیشتر نیز نوشتیم یک ارجاع از نوع قوی ایجاد میکند:
StringBuilder sb= new StringBuilder();
نوع ضعیف
این نوع در عملیات زباله روبی بعدی که انجام میشود از بین میرود. به عنوان مثال اگر ما در برنامه مطمئن نباشیم که آیا از آبجکتی که ساخته ایم قرار است مجددا استفاده شود یا خیر از این نوع استفاده میکنیم. در این صورت اگر Garbage Collector شروع به فعالیت کند، آبجکت ما را حذف خواهد کرد بنابراین اگر مجددا در سورس کد (Source Code)سورس کد چیست؟ آیا سورس کد یا سورس برنامه قابلیت اجرا دارند؟این مقاله عالی به سورس کد یا سورس برنامه پرداخته؛ همچنین به بررسی اهداف سورس کد، نحوه ساخت سورس کد و اینکه آیا سورس کد ها قابلیت اجرا دارند پرداخته نوشته شده بخواهیم از این شی استفاده کنیم، با یک Null Value مواجه میشویم. برای ساخت یک آبجکت با ارجاع ضعیف میتوانیم از کتابخانه java.lang.ref.WeakReference به صورت زیر استفاده کنیم:
WeakReference reference = new WeakReference<>(new StringBuilder());
نوع نرم
آبجکت های تعریف شده از این نوع تنها زمانی زباله روبی میشوند که برنامه ی مورد نظر دچار کمبود حافظه شود. البته موقع اجرا شدن Garbage Collector، ارجاعات نوع نرم زباله روبی نمیشوند، بلکه زمانی حذف میشوند که برنامه دچار خطای OutOfMemoryError شود. با استفاده از کد زیر میتوانیم یک ارجاع از نوع نرم بسازیم:
SoftReference reference = new SoftReference<>(new StringBuilder());
نوع فانتوم
این نوع در پکیج java.lang.ref قرار دارد و در کلاس java.lang.ref.PhantomReference تعریف شده است. آبجکت هایی که ارجاعی از این نوع دارند در واقع هر زمان که Garbage Collector بخواهد آنها را نابود میکند! با استفاده از کد زیر میتوانیم یک ارجاع از نوع فانتوم بسازیم:
PhantomReference reference = new PhantomReference<>(new StringBuilder());
حوزه پشته (Stack Area)
حوزه پشته زمانی ایجاد میشود که یک نخ یا Thread ساخته میشود. اندازه حوزه ی پشته نیز میتواند ثابت و یا پویا باشد. هر Thread دارای حافظه پشته مخصوص خود میباشد. از این حافظه برای ذخیره نتایج دادهها و Partial Resultها استفاده میشود، همچنین این فضا دارای ارجاعاتی به آبجکتهای واقع در هیپ میباشد و مقادیرمتغیر متغیر در برنامه نویسی چیست ⚡️انواع متغیر در برنامه نویسیاین صفحه عالی بررسی کرده متغیر در برنامه نویسی چیست و انواع متغیر در برنامه نویسی را معرفی و مراحل کار با متغیر، نحوه تعریف و قوانین نامگذاری متغیرها را گفته ها نیز در این حوزه ذخیره میشوند. متغیرهایی که در پشته ذخیره میشوند، هرکدام دارای حوزه یا Scope مشخصی هستند.
Stack Frame: استک فریم ساختمان دادهآموزش ساختمان داده و الگوریتمهر ساختمان داده یک نوع فرمت ذخیرهسازی و مدیریت دادهها در کامپیوتر است، که امکان دسترسی و اصلاح کارآمد آن دادهها را برای یکسری از الگوریتمها و کاربردها فراهم میکند، در این صفحه به بررسی و آموزش ساختمان داده و الگوریتم پرداخته شده استای است که شامل داده Threadها میباشد. دادههای نخها معمولا وضعیت فعلی نخ (State) هستند که در متد در حال اجرا قرار دارند. میتوان گفت این ساختمان داده وظایف مهمی را بر عهده دارد که به طور خلاصه در لیست زیر جمعآوری شدهاند:
- برای ذخیره ی دادهها و Partial Resultها استفاده میشود.
- وقتی یک متد فراخوانی میشود، یک فریم جدید ایجاد میشود و وقتی کار متد به پایان رسید، فریم ایجاد شده حذف میشود.
- هر فریم دارای آرایهآموزش آرایه در ساختمان داده به زبان ساده و از 0 تا 100در این مقاله موارد زیر بررسی شده است : 1- آرایه چیست 2- انواع اندیس گذاری در آرایه 3- انواع آرایه 4- محاسبه آدرس در آرایه 5- محاسبه شماره در آرایه 6- آرایه در برنامه نویسی 7- مزایای استفاده از آرایه متغیر محلی یا Local Variable Array (LVA)، پشته عملوند (Operand Stack) و دادههای فریم (Frame Data) مربوط به خود است که در شکل اول این مقاله قابل مشاهده است.
- اندازه LVA، OS و FD در زمان شروع کار کامپایلر (Compiler)کامپایلر چیست و چگونه کار میکند و چرا از آن استفاده میشود؟کامپایلر (Compiler) یک برنامهی خاص برای ترجمه سورس کدهای (Source Code) یک زبان برنامه نویسی، به زبان ماشین یا بایت کد و یا یک زبان برنامه نویسی دیگر است مشخص میشود.
- تنها یک فریم در آن واحد فعال است (فریم مربوط به متد در حال اجرا).
- زمانی که کار یک متد به اتمام رسیده باشد و یا درون متد یک متد دیگری صدا زده شود، فریم فعلی متوقف میشود.
- یک فریم ایجاد شده توسط یک نخ تنها توسط همان نخ قابل مشاهده است و مابقی نخها نمیتوانند به آن دسترسی داشته باشند.
پشته متد نیتیو (Native Method Stack)
این پشته برای کدهای نیتیو که به زبان هایی غیر از زبان جاوا (معمولا زبان برنامه نویسی C زبان برنامه نویسی C – مزایا و کاربرد زبان C – فرق C و ++Cاین مقاله عالی ابتدا توضیح میدهد که زبان برنامه نویسی c چیست، سپس به بررسی مزایا و معایب زبان C ، کاربردهای زبان سی ، و تفاوت بین C و ++C میپردازد) نوشته شدهاند استفاده میشود. مسئول فراخوانی پشته نیتیو نیز Java Native Interface (JNI) است. پرفورمنس پشته نیتیو بستگی به سیستم عاملسیستم عامل چیست به زبان ساده، چرا باید از OS استفاده کنیم؟این مقاله عالی به معرفی سیستم عامل (Operating System|OS) به زبان ساده پرداخته، همچنین بررسی کرده که چرا باید از سیستم عامل استفاده کنیم مورد استفاده دارد.
ثبات های PC (PC Registers)
هر Thread یک ثبات شمارنده برنامه یا Program Counter (PC) مربوط به خود دارد. به طور ساده، ثبات PC آدرسهای برگشت یا Return Address و یا Native Pointerها را نگه داری میکند. از دیگر مواردی که این ثبات ذخیره میکند میتوان به دستورالعمل های فعلی در حال اجرای JVM اشاره کرد.
کارکرد Garbage Collector
زمانی که یک برنامه جاوا اجرا میشود، به صورت های مختلفی از حافظهحافظه در کامپیوتر، همه چیز در مورد حافظه در معماری کامپیوتردر این مقاله به بررسی کامل حافظه در کامپیوتر، انواع حافظه در کامپیوتر، کش، روشهای آدرس دهی کش، نگاشت آدرس و موارد دیگر میپردازیم استفاده میکند. فضای هیپ بخشی است که آبجکت ها در آن قرار دارند و تنها حافظهای است که شامل حال فرایند زباله روبی میشود. Garbage Collectorها باید مطمئن شوند که هیپ از میزان فضای خالی مناسبی برخوردار است. عملکرد Garbage Collection به این صورت است که به دنبال آبجکتهایی میگردد که دسترسی به آنها در ادامه برنامه ی در حال اجرا ممکن نخواهد بود.
تخصیص آبجکت (Object Allocation)
وقتی یک آبجکتی تعریف شد، JRockit JVM اندازه آبجکت را بررسی میکند تا بین آبجکت های کوچک یا حجیم تفاوت قائل شود. اندازه آبجکت به موارد مختلفی از جمله ورژن JVM، اندازه هیپ، استراتژی زباله روب و پلتفرم مورد استفاده بستگی دارد. به طور کلی اندازه یک آبجکت بین 2 تا 128 کیلوبایت است. آبجکتهای کم حجم درون فضای محلی نخها یا Thread Local Area (TLA) ذخیره میشوند که قسمت خالی از فضای هیپ است. TLA با بقیه نخها هماهنگ (Synchrone) نیست. زمانی که یک TLA پر شود، درخواستی برای یک TLA جدید صادر میشود. از طرف دیگر، آبجکتهای حجیم به طور مستقیم داخل TLA مستقر در هیپ جا نمیشوند. اگر یک نخ در حال استفاده از فضای Young باشد، این آبجکتها به طور مستقیم درون Old Space ذخیره میشوند. آبجکتهای حجیم به هماهنگ سازی بیشتری بین نخها نیاز دارند.
Garbage Collector جاوا چیست؟
کنترل کردن GarbageCcollector بر عهده JVM است. JVM تصمیم میگیرد چه زمانی عملیات زباله روبی اجرا شود. ما نیز میتوانیم به JVM به صورت دستی درخواست اجرای زباله روبی دهیم. البته تحت هیچ شرایطی هیچ تضمینی برای موافقت JVM نخواهد بود. JVM به طور کلی زمانی Garbage Collector را فعال میکند که احساس کند حافظه در حال تمام شدن است. در اینجا 2 سوال مطرح میشود:
- چه زمانی یک آبجکت واجد شرایط زباله روبی میشود؟ هر برنامه ی جاوا بیش از یک Thread دارد. هر Thread نیز پشته مخصوص به خود را دارد. اگر آبجکتی وجود داشته باشد که هیچ کدام از نخ های موجود قادر به دسترسی به آن نباشند، آن آبجکت مشمول زباله روبی خواهد شد. اما اگر برنامه یک ارجاع داشته باشد که به آن آبجکت اشاره کند، عملیات زباله روبی بر روی این آبجکت انجام نخواهد شد. به این آبجکتها به اصطلاح آبجکتهای قابل دسترس یا Reachable میگویند.
- آیا یک برنامه ی نوشته شده به زبان جاوا دچار کمبود حافظه میشود؟ در جواب کوتاه بله؛ Garbage Collection تنها زمانی آبجکتها را حذف میکند که در حال استفاده نباشند بنابراین اگر تعداد زیادی آبجکتهای در حال استفاده داشته باشید، Garbage Collector هیچ ضمانتی برای کافی بودن فضای حافظه نمیدهد و تنها حافظه باقی مانده به طور کارآمد مدیریت میشود.
انواع Garbage Collection
به طور کلی 5 نوع Garbage Collection داریم:
- Serial GC: این نوع زباله روب از رویکرد نشانه گذاری (Mark) و جارو کردن (Sweeps) برای Young Generation و Old Generation استفاده میکند. (این موارد را جلوتر توضیح میدهیم.)
- Parallel GC: شبیه به Serial GC عمل میکند با این تفاوت که N نخ (تعداد هسته های CPU سیستم مورد نظر) برای Young Generation تولید میکند.
- Parallel Old GC: شبیه به Parallel GC عمل میکند با این تفاوت که از چند نخ برای هر دو Generation ذکر شده استفاده میکند.
- Concurrent Mark Sweep (CMS) Collector: زباله روبی مربوط به Old Generation بر عهده ی این نوع است. تعداد نخ های مربوط به CMS Collector میتواند تنظیم شود.
- G1 Garbage Collector: این نوع، در جاوا 7 معرفی شد. هدف این نوع، جایگزینی CMS Collector است. این نوع به صورت موازی و همزمان (Concurrent) کار میکند، همچنین دیگر خبری از Young Generation و Old Generation نخواهد بود. در این نوع، فضای هیپ به چندین قسمت با سایز یکسان تقسیم میشود. قسمتهایی که داده کمتری در آن در دسترس هستند زودتر زباله روبی میشوند.
الگوریتم های Mark و Sweep
JRockit JVM از الگوریتم های Mark و Sweep برای انجام عملیات زباله روبی استفاده میکند. برای اینکار دو فاز Mark و Sweep انجام میشود:
فاز Mark: آبجکتهایی که از طریق نخها، Native Handlesها و یا ریشههای GC دیگری قابل دسترس هستند، یک نشان Live یا زنده به آنها زده میشود. هر درخت مربوط به شی دارای بیش از یک ریشه میباشد. ریشه GC همیشه در دسترس است. بنابراین هر آبجکت دارای یک ریشه GC یا Garbage Collection به عنوان ریشه خود است و مشمول زباله روبی نخواهد شد. هر آبجکتی که این شرایط را نداشته باشد به عنوان زباله حذف خواهد شد. در تصویر زیر این امر به طور ساده مشخص شده است:
فاز Sweep: در این مرحله، پشته برای یافتن شکاف (Gap) بین آبجکت های Live پیمایش میشود. این شکافها در لیست آزاد ثبت میشوند و برای تخصیص شی جدید در دسترس هستند. دو نوع نسخه ی تعمیم یافته از الگوریتم Mark و Sweep وجود دارد:
- Concurrent Mark and Sweep
- Parallel Mark and Sweep
هرکدام از این روشها نیز مزایا و معایب مخصوص به خود را دارند.
جمعبندی
مدیریت حافظه از جمله مواردی است که در دنیای کامپیوترکامپیوتر چیست؟ ⚡️ کامپیوتر چیست به زبان سادهاین مقاله عالی توضیح داده که کامپیوتر چیست و چه کاربردی دارد و همه چیز درباره کامپیوتر از جمله فواید کامپیوتر و تعریف کامپیوتر و اجزای آن را بیان کرده است از اهمیت بالایی برخوردار است. بسیاری از زبان های برنامه نویسی دارای سیستم های مدیریت حافظهای خودکار هستند تا کار برنامه نویس را راحت تر کند. معمولا زبان های سطح بالاتر مانند جاوا و دارای این خاصیت هستند و زبان های سطح پایین تر مانند سی پلاس پلاس وظیفه مدیریت حافظه را به خود برنامه نویس سپرده است. در این مقاله به طور کامل به مدیریت حافظه در زبان برنامه نویسی جاوا پرداخته شد و زوایای مختلف و مهم ساختار این زبان از لحاظ مدیریت حافظه را بررسی کردیم.
آیا در زبان جاوا مدیریت حافظه به صورت دستی انجام میشود؟
برخلاف زبان هایی مانند C و C++، زبان جاوا عملیات مدیریت حافظه را به صورت خودکار انجام میدهد و نیازی به خالی کردن حافظه به صورت دستی نیست. در جاوا وقتی هیچ ارجاعی به یک آبجکت وجود نداشته باشد، آن آبجکت بوسیله سیستم Garbage Collector حذف خواهد شد.
آیا Garbage Collection خودکار تاثیری روی پرفورمنس برنامه دارد؟
در پاسخی کوتاه باید گفت بله. Garbage Collection جاوا میتواند روی پرفورمنس کلی تاثیر بگذارد که البته بسته به نوع تعریف و استفاده از آبجکتها این اثر گذاری متفاوت خواهد بود.