فصل 5: جزئیات داخلی JVM در جاوا

20 مرداد 1397
java-jvm-variables

همانطور که در جلسات پیش گفته شد، JVM یک ماشین مجازی است که محیط اجرایی برای بایت کدهای جاوا را فراهم می کند. از آنجایی که JVM به پلتفرم خود وابسته‌ست، JVMهای مختلفی برا پلتفرم های سخت افزاری و نرم افزاری موجود است.

JVM چیست

JVM در واقع

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

وظایف JVM

JVM کارهای زیر را می کند:

  • لود کردن کد
  • تایید کردن کد
  • اجرای کد
  • فراهم کردن محیط اجرا

و به موارد زیر معنا می بخشد:

  • فضای حافظه
  • فرمت فایل کلاس
  • مجموعه رجیستر
  • هیپ (پشته) جمع‌آوری زباله
  • گزارش خطاهای مهلک

معماری JVM

معماری JVM را به طور خلاصه در تصویر زیر مشاهده می کنید که شامل کلاس‌لودر، فضای حافظه و موتور اجرا می باشد.

1- کلاس‌لودر

کلاس‌لودر زیر مجموعه ای از JVM می باشد که کلاس ها را بارگذاری می کند. هر موقع که یک برنامه جاوا اجرا شود، ابتدا توسط کلاس‌لودر خوانده می شود. جاوا دارای سه کلاس‌لودر داخلی می باشد.

  1. کلاس‌لودر بوت استرپ: اولین کلاس‌لودر که در واقع کلاس پدر برای کلاس‌لودر Extension می باشد. این کلاس‌لودر فایل jar را که شامل پکیج های استاندارد جاوا همچون util، lang و io می باشد بارگذاری می کند.
  2. کلاس لودر Extension: در واقع کلاس فرزند برای بوت استرپ و پدر برای کلاس‌لودر سیستم می باشد. فایل های jar در دایرکتوری $JAVA_HOME/jre/lib/ext را بارگذاری می کند.
  3. کلاس‌لودر سیستم یا برنامه: این کلاس‌لودر در واقع فایل‌های کلاس را از مسیر کلاس یا classpath می خواند. مسیر کلاس به طور پیش فرض دایرکتوری جاری میباشد اما با سویچ classpath یا –cp می توان آنرا تغییر داد.

در صورتی که بخواهید کلاس لودر دلخواه خود را بنویسید، باید از کلاس ClassLoader ارث‌بری کنید و کلاس خودتان را ایجاد نمایید.

//Let's see an example to print the classloader name  
public class ClassLoaderExample  
{  
    public static void main(String[] args)  
    {  
        // Let's print the classloader name of current class.   
        //Application/System classloader will load this class  
        Class c=ClassLoaderExample.class;  
        System.out.println(c.getClassLoader());  
        //If we print the classloader name of String, it will print null because it is an  
        //in-built class which is found in rt.jar, so it is loaded by Bootstrap classloader  
        System.out.println(String.class.getClassLoader());  
    }  
}

خروجی:

sun.misc.Launcher$AppClassLoader@4e0e2f2a
null

2- فضای کلاس یا متد

فضای کلاس یا متد، ساختارهایی همچون منبع ثابت اجرایی، اطلاعات مربوط به متدها و فیلدها و کد مربوط به متدها را نگهداری می کند.

3- هیپ (Heap)

فضایی است که هنگام اجرای برنامه به اشیا تخصیص داده می شود.

4- استک (stack)

استک جاوا فریم‌ها را در خود ذخیره می کند، متغیرهای محلی و نتایج مقطعی را نگه میدارد و در صدا زدن و خروجی دادن متدها هم نقش مهمی ایفا می کند. هر ریسه یک استک خصوصی ماشین مجازی جاوا را دارد که همزمان با خود ریسه ساخته می شود.

با صدا زدن یک متد، یک فریم ساخته می شود و پس از اتمام کار متد، فریم از بین می رود.

5- رجیستر شمارنده برنامه

شمارنده برنامه (PC) شامل آدرس دستورات JVM که در حال اجرا هستند، می باشد.

6- استک متد محلی

شامل تمامی متدهای محلی موجود در برنامه می باشد.

7- موتور اجرا

موتور اجرا شامل موارد زیر می شود:

  • یک پردازنده مجازی
  • مفسری که بایت کد را می خواند و دستورات را اجرا می کند.
  • کامپایلر همزمان یا JIT: این کامپایلر برای بهبود عملکرد مورد استفاده قرار می گیرد و با اجرای همزمان قسمت هایی از کد که کارکرد یکسانی دارند باعث کاهش زمان اجرا می شود. در اینجا کامپایلر به مترجمی اشاره دارد که مجموعه دستورات JVM را به مجموعه دستورات CPU تبدیل می کند.

8- رابط ‌کاربری محلی جاوا

Java Native Interface یا JNI فریم ورکی است که رابط کاربری مورد نیاز برای ارتباط با برنامه های نوشته شده در زبان های دیگر همچون سی، اسمبلی را فراهم می کند. جاوا همچنین برای فرستادن خروجی در کنسول یا ارتباط با کتابخانه های سیستم عامل از JNI استفاده می کند.

متغیرهای جاوا

متغیر یک ظرفی می باشد که مقداری را در هنگام اجرای برنامه در جاوا نگه داری می کند. مقدار درون متغیر از جنس یک نوع داده می باشد. در واقع میشود گفت که متغیر نامی برای محل حافظه است.

در جاوا سه نوع متغیر وجود دارند: local یا محلی، instance یا نمونه و استاتیک.

به طور کل نیز دو نوع داده داریم: 1- بدوی یا اولیه 2- غیراولیه

متغیر

متغیر نامی برای فضای تخصیص داده شده در حافظه یا به بیان دیگر نامی برای خانه محل حافظه است. علت نامگذاریش به متغیر، امکان تغییر مقدار متغیر می باشد.

انواع متغیر

سه نوع متغیر در جاوا وجود دارند:

  1. محلی
  2. نمونه
  3. استاتیک

متغیر محلی

به متغیری که در بدنه یک متد تعریف می شود متغیر محلی می گویند. امکان استفاده از این متغیر فقط در همان متد میسر می باشد و در واقع متدهای دیگر از وجود این متغیر آگاه نیستند.

متغیر محلی را نمیتوان استاتیک تعریف کرد.

متغیر نمونه

به متغیری که بیرون از بدنه متد اما در کلاس تعریف شده است می گویند. متغیر نمونه هم نمی تواند استاتیک باشد.

علت نام گذاریش به متغیر نمونه این است که مقدارش مختص به یک نمونه ساخته شده از یک کلاس می باشد و بین تمام نمونه ها و اشیاهای ساخته شده از یک کلاس مشترک نیست

متغیر استاتیک

متغیری که با کلمه کلیدی Static تعریف شود را متغیر استاتیک می گویند. متغیر استاتیک بین تمام اشیا و نمونه های ساخته شده از یک کلاس مشترک می باشد و به همین دلیل تنها یکبار هنگام لود شدن کلاس به آن حافظه تخصیص داده می شود.

مثالهایی برای درک نحوه عملکرد متغیرها

class A{  
int data=50;//instance variable  
static int m=100;//static variable  
void method(){  
int n=90;//local variable  
}  
}//end of class

جمع دو عدد:

class Simple{  
public static void main(String[] args){  
int a=10;  
int b=10;  
int c=a+b;  
System.out.println(c);  
}}

خروجی:

20

گسترش یا Widening:

class Simple{  
public static void main(String[] args){  
int a=10;  
float f=a;  
System.out.println(a);  
System.out.println(f);  
}}

خروجی:

10
10.0

تایپ کستینگ (تبدیل نمونه ها به یکدیگر):

class Simple{  
public static void main(String[] args){  
float f=10.5f;  
//int a=f;//Compile time error  
int a=(int)f;  
System.out.println(f);  
System.out.println(a);  
}}

خروجی:

10.5
10

اورفلو Overflow:

class Simple{  
public static void main(String[] args){  
//Overflow  
int a=130;  
byte b=(byte)a;  
System.out.println(a);  
System.out.println(b);  
}}

خروجی:

130
-126

اضافه کردن بایت ها و تایپ کستینگ

class Simple{  
public static void main(String[] args){  
byte a=10;  
byte b=10;  
//byte c=a+b;//Compile Time Error: because a+b=20 will be int  
byte c=(byte)(a+b);  
System.out.println(c);  
}}

خروجی:

20
نویسنده شوید

دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد
12 آبان 1397
دوست عزیز کی گفته متغیر نمونه نمیتونه استاتیک باشه؟پس متغر از نوع stringچیه؟ک استاتیک هم میشه تعریفش کرد. البته فقط این نیست...

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.