آشنایی با ماشین مجازی جاوا

در این آموزش قصد داریم تا به تفصیل مفوم JVM یا همان ماشین مجازی جاوا را مورد بررسی قرار دهیم. در واقع از بدو ایجاد زبان برنامه نویسی جاوا شعار طراحان این زبان محبوب این بوده است که Write One, Run Anywhere! به این معنی که “یک بار برنامه جاوای خود را بنویسید سپس روی هر پلتفرمی که خواستید آن را اجرا کنید!” که چنین قابلیتی جز با به کاری گیری مفهومی تحت عنوان “ماشین مجازی جاوا” امکان پذیر نخواهد بود. به طور کلی ماشین مجازی جاوا را می توان در قالب تصویر زیر نشان داد:

همانطور که در تصویر بالا مشخص است، برنامه جاوایی که ما می نویسیم یا همان سورس کد برنامه ابتدا توسط جاوا کامپایل می شود. منظور از اصطلاح Compile تبدیل کدهای جاوا به بایت کد است. در واقع ما یک بار بیشتر برنامه خود را کامپایل نخواهیم کرد و این برنامه Compiled شده برای هر یک از پلتفرم های موجود از قبیل ویندوز، مکینتاش، لینوکس و … یکسان خواهد بود (لازم به ذکر است که اصطلاح Compiled یک صفت در انگلیسی محسوب می شود نه گذشته فعل Compile)

از این پس این وظیفه ماشین های مجازی است که برنامه Compiled شده را به شکلی که برای پلتفرم مد نظر قابل فهم است تبدیل نماید. به عبارت دیگر ماشین های مجازی تمام تلاش خود را به کار خواهند بست تا از روی کد یکسانی نتایج نسبتاً یکسانی را در پلتفرم های مختلف ایجاد کنند. اکنون پس از آشنایی با نحوه عملکرد ماشین مجازی، قصد داریم تا بیشتر درباره ماهیت خود این ماشین مجازی نکاتی را بیان کنیم:


همانطور که در تصویر فوق مشخص است ماشین مجازی جاوا را می توانیم به عنوان یک لایه مجازی مابین برنامه جاوای نوشته شده و سیستم عاملی که قرار است آن برنامه روی آن اجرا شود تلقی کرد. از سوی دیگر این ماشین مجازی هیچ کاری با سورس برنامه ما نخواهد داشت چرا که برنامه ما ابتدا Compile خواهد شد که در این پروسه همان طور که قبلاً گفته شد، به زبان قابل فهم برای سیستم تبدیل می شود که اصطلاحاً Bytecode نامیده می شود. سپس این زبان قابل فهم برای سیستم مورد استفاده ماشین مجازی قرار می گیرد تا برای سیستم عامل های مختلف بهینه شود.

یکی از مزایای به کارگیری از Bytecode این است که از این طریق می توان دیگر زبان های برنامه نویسی را نیز داخل جاوا به کار برد. به عبارت دیگر، چنانچه زبان برنامه نویسی یی وجود داشته باشد که بتواند خود را به Bytecode قابل فهم برای جاوا Compile کند، ماشین مجازی جاوا خواهد توانست  آن بخش از کدی را که در زبان دیگری نوشته شده است را نیز در کنار کدهای جاوا اجرا سازد.

آشنایی با مفهوم Garbage Collection
منظور از واژه Garbage در زبان انگلیسی “زباله” است و واژه Collection نیز به معنی “جمع آوری” می باشد. زمانی که در زبان برنامه نویسی جاوا از این اصطلاح استفاده می کنیم منظور این است که ما به عنوان یک برنامه نویس جاوا نیازی نیست تا خود را درگیر مسائل مربوط به Memory یا “حافظه” کنیم چرا که این وظیفه ای است که بر عهده خود ماشین مجازی جاوا گذاشته شده است. برای روشن شدن نحوه عملکرد Garbage Collection مثالی می زنیم. حافظه در داخل برنامه‌های جاوا به دو قسمت تقسیم می‌شود، حافظه‌ی Heap و حافظه‌ی Stack. وقتی در یک برنامه آبجکتی را ایجاد می کنیم، مثلا شیئی از روی کلاس String ایجاد می کنیم:

String str = new String();

آبجکت تولید شده در حافظه‌ی Heap ذخیره می‌شود. توجه داشته باشید که str شیء نیست، بلکه ارجاعی به شیء ساخته شده در حافظه‌ی هیپ است. بنابراین متغیر str در حافظه‌ی Stack ذخیره شده است. در جاوا مفهوم اشارگر وجود ندارد اما در این قسمت می‌توان گفت که str یک نوع اشارگر است زیرا به شیئی که ساخته‌ایم در حافظه‌ی هیپ اشاره می‌کند.

در بیشتر منابع آموزشی گفته می‌شود که متغیر‌هایی مانند str شیء هستند که صحیح نیست! اما تقریبا تمام افراد متغیر‌هایی مانند str را با نام شیء صدا می‌کنند (حتی کسانی که از این موضوع با خبر هستند چرا که در گفتن راحت‌تر است.) بعد از این که آبجکت را ایجاد کردیم، با اجرای برنامه و در جایی از برنامه، آبجکت مورد نظر استفاده می‌شود و بعد از آن اگر دیگر از آن آبجکت استفاده نشود، آن آبجکت یک شیء «مُرده» به حساب می‌آید.

در زبان‌هایی مانند سی پلاس پلاس حذف کردن آبجکت‌های مُرده توسط برنامه نویس انجام می‌شود که این کار در برنامه‌های بزرگ و پیچیده به علت ارجاعات متعددی که آبجکت‌ها با یکدیگر دارند، فرآیندی بسیار سخت، پیچیده و پر خطا است اما در جاوا یک قابلیتی وجود دارد به نام Garbage Collector که وظیفه‌ی حذف آبجکت‌های مُرده در حافظه‌ی هیپ را بر عهده دارد. Garbage Collector بخشی از JVM است و الگوریتم‌های بسیار پیچیده‌ای دارد و فقط این را بدانید که هر از چند گاهی گاربج کالکتور به حافظه‌ی هیپ سر می‌زند و آبجکت‌های مُرده را پاک می‌کند تا حافظه آزاد شود. دقت داشته باشید که گاربج کالکتور فقط حافظه‌ی هیپ را پاک می‌کند. البته برنامه نویس هم می‌تواند گاربج کالکتور را فراخوانی کند، اما این کار اصلا توصیه نمی‌شود.

 نکته
ماشین مجازی جاوا علاوه بر قابلیت های بسیاری که در اختیار برنامه نویسان می دهد محدودیت هایی را هم ایجاد می کند که البته این محدودیت ها جزو محدودیت های راه گشایی هستند که منجر به ارتقاء امنیت نرم افزارهای نوشته شده با زبان برنامه نویسی جاوا می شوند. به عبارت دیگر ماشین مجازی جاوا این اجازه را به هیچ وجه به ما نمی دهد تا بخشی از حافظه را که در اختیار دیگر بخش های برنامه است را به زور تصاحب کنیم تا بواسطه آن بتوانیم مثلاً یک شیئ جدید ایجاد کنیم.

شاید این مطالب را هم دوست داشته باشید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.