چارچوب NET. و ارتباط آن با #C (قسمت دوم)

 

MSIL و JIT

هنگامی که برنامه ای که در آن از توابع موجود در کتابخانه کلاس NET. استفاده شده است را کامپایل می کنید، بلافاصله کد قابل فهم برای سیستم عامل تولید نمی شود. در عوض کد شما به زبانی به نام زبان سطح میانی مایکروسافت و یا به اختصار MSILتبدیل می شود. این کد برای سیستم عامل خاصی نیست و همچنین منحصر به زبان #C و یا هر زبان دیگری نیز نیست. به عبارت دیگر کد زبان های دیگر نیز می تواند به MSIL تبدیل شود (و البته باید تبدیل شود). کدهای زبان های دیگری نیز که از چارچوب NET. استفاده می کنند، هنگام کامپایل ابتدا به زبان MSIL تبدیل می شوند. هنگام استفاده از ویژوال استودیو برای نوشتن برنامه، این مرحله از کامپایل توسط ویژوال استودیو انجام می شود.

اما برای اجرای یک برنامه توسط سیستم عامل یک مرحله دیگر نیز مورد نیاز است. این مرحله وظیفه ی Just-In-Time کامپایلر و یا به اختصار JIT کامپایلر است. این کامپایلر کد MSIL یک برنامه را دریافت کرده و آن را به کدی تبدیل می کند که به وسیله ی سیستم عامل قابل اجرا باشد. بعد از اینکه این تبدیل توسط JIT انجام شد، سیستم عامل می تواند برنامه را اجرا کند. همان طور که از اسم این قسمت نیز مشخص است، کدهای زبان MSIL فقط هنگامی به زبان محلی قابل فهم برای سیستم عامل تبدیل می شوند که بخواهند اجرا شوند.

در گذشته برای اینکه بتوانید برنامه خود را بر روی سیستم عامل های مختلف اجرا کنید نیاز داشتید که برای هر نسخه از سیستم عامل، آن کد را یک مرتبه به طور کامل کامپایل کنید. اما در چارچوب NET. نیازی به این کار نیست؛ زیرا برای هر نوع سیستم عامل، یک نسخه از JIT وجود دارد. برنامه شما در هر سیستم عاملی که اجرا شود، کامپایلر JIT موجود در آن سیستم عامل کد MSIL برنامه ی شما را که مستقل از سیتم عامل است دریافت کرده و کد محلی مناسبی تولید می کند که برای سیستم عامل قابل فهم است.

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

اسمبلی ها

هنگامی که یک برنامه را کامپایل می کنید کد MSIL تولید شده در فایل هایی به نام اسمبلی (مفهوم اسمبلی در اینجا کاملا با زبان برنامه نویسی اسمبلی تفاوت دارد) ذخیره می شود. فایل های اسمبلی می توانند شامل برنامه هایی باشند که بدون نیاز به برنامه ای دیگر بتوانند اجرا شوند (این گونه فایل ها دارای پسوند exe. هستند) و یا شامل کتابخانه هایی از کلاس ها و توابع برای استفاده در دیگر برنامه ها یاشند (این گونه فایل ها دارای پسوند dll. هستند)

فایل های اسمبلی علاوه بر کدهای MSIL شامل اطلاعات متا (اطلاعاتی راجع به اطلاعات ذخیره شده در فایل اسمبلی، Meta Data) و همچنین منابع اختیاری (اطلاعات اضافی که به وسیله ی کدهای MSIL استفاده می شوند همانند فایل های صوتی یا تصویری) نیز هستند. اطلاعات متا باعث می شوند که یک فایل اسمبلی بتواند اطلاعات داخل خود را به طور کامل توصیف کند. به عبارت دیگر برای استفاده از یک اسمبلی به هیچ اطلاعات و یا کارهای اضافی مانند ثبت آن در رجیستری سیستم نیازی ندارید. به این ترتیب از مشکلاتی که عموما هنگام کار با این نوع فایل ها در محیط های دیگر به وجود می آمد نیز جلوگیری می شود. 

یکی دیگر از خاصیت های این مورد در این است که توزیع یک نرم افزار به سادگی کپی کردن تمام فایل های آن بر روی کامپیوتر مقصد است. به علت اینکه برای اجرای یک فایل اسمبلی به هیچ مورد دیگری نیاز نیست، می توانید به سادگی فولدر حاوی برنامه را بر روی کامپیوتر مقصد کپی کنید و با انتخاب فایل اجرایی آن، برنامه را اجرا کنید و از آن استفاده کنید (با فرض اینکه CLR که مهم ترین بخش NET. است قبلا بر روی آن کامپیوتر نصب شده باشد).

البته ممکن است در بعضی مواقع بخواهید از توابع موجود در یک فایل dll در چند برنامه استفاده کنید. برای این کار لازم نیست فایل مذکور را در فولدر تمام برنامه هایی که از آن استفاده می کنند، قرار دهید. بلکه می توانید آن را یک بار در یک مکان مشخص قرار دهید و سپس تمام برنامه هایی که به آن نیاز دارند، از آن استفاده کنند. در چارچوب NET. این مکان مشخص که برای قرار گرفتن فایل های اسمبلی عمومی در نظر گرفته شده است، Global Assembly Cache و یا به اختصار GAC نام دارد. برای اینکه یک فایل اسمبلی را در این قسمت قرار دهید کافیست به سادگی فایل مورد نظر را در فولدر مشخص شده برای GAC کپی کنید، زیرا برنامه ها می توانند علاوه بر اسمبلی های خود به همه ی اسمبلی های موجود در این فولدر نیز دسترسی داشته باشند.

کدهای مدیریت شده

همان طور که گفته شد، برنامه ی شما هنگام کامپایل ابتدا به کد MSIL تبدیل می شود، سپس این کد قبل از اجرا به وسیله ی JIT به کد محلی تبدیل شده و کد محلی به وسیله ی سیستم عامل اجرا می شود. تمام این قسمت ها بخشی از وظایف CLR است، اما وظایف CLR به این موارد ختم نمی شود. برنامه ای که به وسیله ی NET. نوشته شده است در طول زمان اجرا توسط CLR مدیریت می شود. به عبارت دیگر در طول اجرای برنامه های نوشته شده با NET. این بخش مسئول کنترل امنیت آنها، مدیریت حافظه برنامه ها، کنترل بخش های خطایابی در برنامه ها و ... است. به همین دلیل به برنامه هایی که با NET. نوشته شده اند برنامه های مدیریت شده می گویند. در مقابل برنامه هایی که تحت کنترل CLR اجرا نمی شوند به برنامه های مدیریت نشده (Unmanaged Code) معروف هستند و زبان های مشخصی مانند ++C می توانند چنین برنامه هایی تولید کنند. از کدهای مدیریت نشده بیشتر در مواقعی استفاده می شود که قابلیت استفاده از کدهای مدیریت شده نباشد، همانند فراخوانی توابع سطح پایین سیستم عامل. البته با استفاده از زبان #C نمی توان کدهای مدیریت نشده تولید کرد و تمام کدهای تولید شده به وسیله ی کامپایلر #C تحت کنترل CLR اجرا می شوند.

مدیریت حافظه در NET.

یکی از مهم ترین ویژگی های کدهای مدیریت شده، بخش مدیریت حافظه در این نوع کدهاست که به وسیله ی سیستمی به نام Garbage Collection یا به اختصار GC انجام می شود. چارچوب NET. با استفاده از این سیستم می تواند اطمینان حاصل کند که حافظه ای که به یک برنامه اختصاص داده می شود با پایان برنامه به طور کامل بازیابی می شود. در چارچوب های قبل از NET. این مورد به وسیله ی برنامه نویس کنترل می شد و امکان داشت که با یک اشتباه کوچک در کد برنامه مقدار زیادی از فضای حافظه غیر قابل استفاده بماند و برنامه با کمبود حافظه مواجه شود. این گونه مشکلات باعث کاهش سرعت برنامه ها و حتی در بعضی شرایط باعث توقف سیستم می شد.

نحوه ی کار GC درNET. به این صورت است که در زمان های مشخصی به بررسی حافظه می پردازد و داده هایی را که دیگر استفاده نمی شوند از حافظه پاک می کند. البته بررسی حافظه توسط GC در فواصل زمانی ثابت صورت نمی گیرد بلکه ممکن است در شرایطی در هر ثانیه چندین هزار بار اجرا شود و در شرایط دیگر در هر چند ثانیه یک بار اجرا شود.

مراحل اجرای برنامه در NET.

قبل از ادامه، مراحل لازم برای ایجاد یک برنامه با NET. را که در قسمت های قبل توضیح داده شد جمع آوری می کنیم:

1- کد برنامه به وسیله ی یکی از زبان های سازگار با NET. مانند #C نوشته می شود.

2- این کد به زبان MSIL کامپایل می شود و سپس در یک فایل اسمبلی ذخیره می شود.

3- هنگامی که کد بخواهد اجرا شود (چه خود فایل اجرایی باشد و به تنهایی اجرا شود،چه یک فایل حاوی توابع مورد استفاده باشد و به وسیله ی دیگر برنامه ها احضار شود) ابتدا باید به وسیله یک کامپایلر دیگر به کد محلی تبدیل شود، این کامپایلر JIT نام دارد.

4- کد محلی تولید شده به وسیله ی JIT به همراه دیگر برنامه های در حال اجرا که به وسیله ی NET. نوشته شده اند، تحت کنترل CLR به اجرا در می آید.

لینک دادن

در تکمیل گفته های قبلی، فقط یک بخش دیگر باقی مانده است. کد #C یک برنامه که در اولین مرحله به زبان MSIL تبدیل می شود، لزوما نباید در یک فایل باشد، بلکه می توانیم برنامه را در چندین فایل source code قرار دهیم و سپس آنها را در یک فایل اسمبلی کامپایل کنیم. به این عمل لینک کردن گفته می شود که در برنامه ها کاربرد زیادی دارد. فایده ی این روش در این است که معمولا برای برنامه نویس کار با چند فایل کوچک راحت تر از کار با یک فایل بزرگ است؛ به عنوان مثال می توانید source یک برنامه را به چندین فایل مجزا تقسیم کنید و سپس به طور جداگانه بر روی هر یک از آنها کار کنید. به این ترتیب در مواقع مورد نیاز پیدا کردن قسمت خاصی از کد نیز بسیار راحت تر خواهد شد.

یکی دیگر از قابلیت های این روش در این است که گروه های برنامه نویسی می توانند یک برنامه را به چندین قسمت تقسیم کنند. به این ترتیب هر کدام از برنامه نویسان می توانند بر روی یک قسمت خاص کار کنند بدون اینکه در مورد پیشرفت قسمت های دیگر نگران باشند.

---------------------------------------------------------------------------------------------

1- Microsoft Intermediate Language                                                                  

 

/ 0 نظر / 31 بازدید