برنامه نویسی

زمان اجرا زبان رایج (CLR) و زبان متوسط ​​(IL)

Summarize this content to 400 words in Persian Lang

هنگامی که با پلتفرم دات نت کار می کنیم، گزینه های بسیار متنوعی از نظر زبان داریم که می توانیم از آنها برای ایجاد برنامه های خود استفاده کنیم، از جمله C#، F# و Visual Basic که شناخته شده ترین زبان ها هستند. این پلتفرم، اگرچه تنها نیست، از آنجایی که شما می توانید به عنوان مثال از C++ نیز استفاده کنید، همه اینها را به روشی متقابل استفاده کنید، یعنی می توانید برنامه های خود را به هر یک از این زبان ها بسازید و با یکدیگر ارتباط برقرار کنید. بخش هایی از آن به زبان های مختلف که توسط پلتفرم پشتیبانی می شود نوشته شده است.

اما، ممکن است تعجب کنید که چگونه این همه ممکن است؟ این یک جادو است… یا بهتر بگوییم این مهندسی پشت پلت فرم دات نت است که به لطف محیط اجرای آن که بیشتر به نام Common Language Runtime (CLR) شناخته می شود و یک زبان خاص به برنامه ها اجازه می دهد با استفاده از زبان های مختلف با هم ایجاد شوند. برنامه های ما با دات نت به نام زبان میانی (IL) کامپایل شده اند.

کد مدیریت شده و مدیریت نشده

قبل از شروع به یادگیری کمی بیشتر در مورد CLR و IL، باید مفاهیم کد مدیریت شده و مدیریت نشده را بدانیم، این مهم است که برجسته کنیم زیرا یکی از هر دو روشی است که برنامه های ما در سیستمی که روی آن نصب شده اند اجرا می شوند. مقدر شده است.

کد مدیریت شده

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

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

این محیط اجرا به طور رسمی تر به عنوان یک ماشین مجازی یا برنامه کاربردی شناخته می شود که به اختصار PVM (ماشین مجازی در سطح فرآیند) شناخته می شود، که به عنوان هر برنامه کاربردی در سیستم اجرا می شود و از یک فرآیند فردی و مستقل در سیستم عامل پشتیبانی می کند، بنابراین به زبان هایی اجازه می دهد که در آنها استفاده شود. برنامه‌های ما نوشته شده‌اند و با سیستم ارتباط برقرار می‌کنند و واسطه‌ای بین زبان و کد ماشین هستند.

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

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

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

این کدی است که مستقیماً در سیستم عامل اجرا می شود، یعنی هیچ محیط اجرایی یا ماشین مجازی میانی برای اجرا وجود ندارد، بنابراین، این وظیفه توسعه دهنده است که منابعی را که برنامه های خود به آنها دسترسی دارند مدیریت کند تا کارآمد باشند آنها تمایل دارند عملکرد بالاتری نسبت به آنها با کد مدیریت شده داشته باشند زیرا این لایه میانی وجود ندارد و بنابراین فرآیند تفسیر، کامپایل یا تبدیل کد به کد ماشین در طول زمان اجرا وجود ندارد. برنامه‌هایی که به زبان‌هایی نوشته می‌شوند که مستقیماً در کد ماشین مانند C یا C++ کامپایل می‌شوند، نمونه‌هایی از کدهای مدیریت‌نشده هستند، اگرچه به این معنی نیست که ما نمی‌توانیم کدهایی را در C# بنویسیم، مثلاً بدون مدیریت.

بهترین گزینه چیست؟

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

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

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

اگر به دلیل ماهیت پروژه، استفاده از کد مدیریت شده 100٪ غیرممکن است، ممکن است توصیه شود که هر دو طرح را ترکیب کنید: اجزایی که به آن نیاز دارند به عنوان کد مدیریت نشده توسعه داده می شوند و بقیه به عنوان کد مدیریت شده پیاده سازی می شوند.

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

زمان اجرا زبان رایج (CLR)

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

اگر به زبان سی شارپ برنامه نویسی کنیم، CLR، جاوا JVM (ماشین مجازی جاوا) است که بین هر دو پلتفرم پل ارتباطی برقرار می کند و بهترین و نزدیک ترین مثال در این زمینه است، زیرا هدف آن تفسیر، کامپایل یا ترجمه کد میانی است. بین زبان و کد ماشین

از طرف مایکروسافت، آنها به CLR به عنوان یک محیط زمان اجرا مدیریت شده اشاره می کنند که در آن برنامه های نوشته شده به هر یک از زبان های پلت فرم مانند ویژوال بیسیک، سی شارپ یا F# پس از کامپایل شدن به زبان میانی می توانند در CLR اجرا شوند. هنگامی که کد خود را به هر یک از این زبان ها می نویسید، نسخه ای از محیط را برای استفاده و کامپایل ایجاد می کنید، کاری که واقعا انجام می دهید ایجاد اطلاعات توصیفی در مورد برنامه ای است که در برنامه کامپایل شده به عنوان ابرداده ذخیره می شود، این ابرداده در فایل ها exe من dll بیشتر به عنوان اسمبلی شناخته می شود، که در یک زبان میانی و بهینه سازی شده برای اجرا خواهد بود، تمام این اطلاعات به CLR زبانی که برنامه در آن نوشته شده است، نسخه، کتابخانه های کلاس، مراجع و هر چیزی که برنامه برای اجرای خود نیاز دارد، می گوید. به عنوان یک برنامه کاربردی مستقل شناخته می شود که همه چیز لازم برای اجرای آن را در هر ماشینی با محیط اجرا نصب شده دارد.

به این ترتیب، CLR به برنامه های شما اجازه می دهد که مثلاً یک شیء نمونه سازی شده از کلاسی که به یک زبان نوشته شده است، بتواند متد کلاس دیگری را که به زبان دیگری نوشته شده است فراخوانی کند.

توابع CLR

مدیریت حافظه از طریق Garbage Collector.
رسیدگی به استثنا
ایمنی را تایپ کنید
امنیت بین فرآیندها
مدیریت کدهای در حال اجرا

اجزای CLR

Compilador JIT (تدوین به موقع).
کلاس لودر.
استخر نخ.

زبان متوسط ​​(IL)

همچنین به عنوان زبان میانی مایکروسافت (MSIL در بتای زبان‌های دات‌نت) یا زبان متوسط ​​معمولی (CIL) شناخته می‌شود، این کد تولید شده از فرآیند کامپایل برنامه ما است که به زبان انتخابی ما بر روی پلتفرم بدون توجه به این‌ها نوشته می‌شود. است.

زبان متوسط ​​کدی است که سطح انتزاعی پایین تری نسبت به زبان هایی مانند C# یا F# (زبان های سطح بالا) دارد که نوشتن، خواندن و مدیریت آن را برای توسعه دهندگان کمی دشوارتر می کند، اما سطح آن از کد ماشین بالاتر است. خود

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

چیزی که مایکروسافت از طریق زبان میانی به دنبال آن است این است که ما این آزادی را داریم که هر زبانی را که توسط پلتفرم و برنامه دات نت پشتیبانی می شود در این زبان بدون نگرانی در مورد نحوه اجرای آن، علاوه بر داشتن توانایی استفاده از این زبان ها، انتخاب کنیم. با هم برنامه های خود را ایجاد کنیم. این امر با ایجاد زبان میانی با پیروی از مشخصات باز و استاندارد فنی شناخته شده به عنوان زیرساخت زبان مشترک (CLI) به دست آمد، بنابراین به برنامه‌های نوشته شده به هر زبانی اجازه می‌دهد با یکدیگر کار کنند و بر روی انواع مختلف سخت‌افزار اجرا شوند. CLI به نوبه خود شامل سیستم نوع مشترک (CTS) و مشخصات زبان مشترک (CLS) است.

برخی از پیاده سازی های CLI عبارتند از .NET Framework، .NET (یا NET Core) و Mono.

کنجکاوی در مورد CLR و IL

آیا کامپایل JIT توسط CLR برای هر متد، هر بار که فراخوانی می شود، اجرا می شود؟

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

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

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

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

با ژنریک چه اتفاقی می افتد؟

ژنریک ها در دات نت رفتار خاصی در رابطه با کامپایل JIT دارند، زیرا CLR کامپایل آنها را بسته به نوع نمونه سازی آنها به روشی بهینه مدیریت می کند، یعنی اینکه آیا آنها از نوع ارزش (انواع ارزش) یا نوع مرجع هستند ( انواع مرجع) که در زیر توضیح داده شده است:

هنگامی که یک نوع عمومی با یک نوع مقدار (مثلاً int، float، structو غیره)، CLR یک نسخه خاص از روش عمومی را برای هر نوع مقداری که با آن نمونه سازی شده است، جمع آوری می کند. این به این دلیل است که انواع مقادیر در دات نت دارای اندازه و نمایش متفاوتی در حافظه هستند، بنابراین کد تولید شده باید برای هر نوع مقدار منحصر به فرد باشد.

به عنوان مثال، کلاس عمومی List شما از آن استفاده می کنید List y List، CLR دو بیلد متفاوت تولید می کند، یکی برای int و دیگری برای double.

این به این دلیل اتفاق می‌افتد که انواع مقادیر مستقیماً در حافظه ذخیره می‌شوند و کامپایل‌های خاص نحوه مدیریت آن مقادیر را بهینه می‌کنند.

هنگامی که یک نوع عمومی با یک نوع مرجع (مثلاً string، object، یا هر کلاسی که توسط شما تعریف شده باشد)، CLR یک نسخه کامپایل شده را برای همه انواع مرجع به اشتراک می گذارد. یعنی کامپایل JIT یک بار برای همه انواع مرجع انجام می شود، زیرا این انواع همیشه توسط مراجع (اشاره گرها یا آدرس های حافظه) هدایت می شوند و نمایش درون حافظه برای همه انواع مرجع یکنواخت است.

مثلا اگر استفاده می کنید List y List، CLR یک نسخه واحد را برای انواع مرجع کامپایل می کند و از آن برای هر دو مورد استفاده مجدد می کند.

آیا هنگام استفاده از Reflection، کد کامپایل شده توسط JIT نیز در حافظه ذخیره می شود؟

در مورد استفاده از Reflection در دات نت برای فراخوانی متدها، چه عمومی و چه غیر عمومی، کد با استفاده از JIT کامپایل شده و در حافظه ذخیره می شود:

وقتی روشی را با استفاده از Reflection فراخوانی می‌کنید، CLR همچنان باید روش را از IL به کد ماشین با استفاده از JIT کامپایل کند. این به همان صورت اتفاق می افتد که اگر متد مستقیماً در کد فراخوانی شده باشد.
هنگامی که متد JIT کامپایل شد، کد به دست آمده برای استفاده مجدد در فراخوانی های بعدی در حافظه ذخیره می شود، حتی اگر متد از طریق Reflection فراخوانی شده باشد.

JIT اولین باری که فراخوانی می شود متد را کامپایل می کند و کد بومی را در حافظه ذخیره می کند، بنابراین اگر همان روش را دوباره با Reflection فراخوانی کنید، CLR از کد کامپایل شده مجددا استفاده می کند و از کامپایل مجدد آن اجتناب می کند.

عملاً آنچه تغییر می کند نحوه فراخوانی متد است که اگر متد را از کد خود به روش معمولی فراخوانی کنید ثابت یا مستقیم است و پویا یا غیرمستقیم است که وقتی از Reflection اسکن متادیتای انواع استفاده می کنید تا متد را پیدا کنید و آن را اجرا کنید. ; برای CLR مهم نیست که چگونه آن را اجرا می کنید، تنها چیزی که مهم است این است که شما آن را اجرا می کنید و آن را به کد بومی یا ماشینی کامپایل می کند، با این حال، به خاطر داشته باشید که استفاده از Reflection بر عملکرد تأثیر می گذارد، اما این چیزی برای این کار را با CLR انجام دهید، بلکه با استفاده از بازرسی نوع و کشف نوع در زمان اجرا با استفاده از Reflection انجام دهید.

به این ترتیب، هنگامی که متد به کد بومی کامپایل شد، هم برای فراخوانی مستقیم و هم برای فراخوانی با Reflection، کد کامپایل شده ذخیره شده و مجددا استفاده می شود. این بدان معنی است که فرآیند ساخت خود تکرار نمی شود، اما بخش پویا فراخوانی از طریق Reflection (جستجو و فراخوانی) همچنان کندتر است زیرا همیشه انجام خواهد شد.

منابع اضافی

https://www.geeksforgeeks.org/common-language-runtime-clr-in-c-sharp/

https://en.wikipedia.org/wiki/Common_Intermediate_Language

https://www.artima.com/articles/clr-design-choices

https://snifftontechnologies.wordpress.com/2014/03/05/what-is-common-language-runtime-in-c/

CLR و IL روی نوعی CPU می نویسند

هنگامی که با پلتفرم دات نت کار می کنیم، گزینه های بسیار متنوعی از نظر زبان داریم که می توانیم از آنها برای ایجاد برنامه های خود استفاده کنیم، از جمله C#، F# و Visual Basic که شناخته شده ترین زبان ها هستند. این پلتفرم، اگرچه تنها نیست، از آنجایی که شما می توانید به عنوان مثال از C++ نیز استفاده کنید، همه اینها را به روشی متقابل استفاده کنید، یعنی می توانید برنامه های خود را به هر یک از این زبان ها بسازید و با یکدیگر ارتباط برقرار کنید. بخش هایی از آن به زبان های مختلف که توسط پلتفرم پشتیبانی می شود نوشته شده است.

اما، ممکن است تعجب کنید که چگونه این همه ممکن است؟ این یک جادو است… یا بهتر بگوییم این مهندسی پشت پلت فرم دات نت است که به لطف محیط اجرای آن که بیشتر به نام Common Language Runtime (CLR) شناخته می شود و یک زبان خاص به برنامه ها اجازه می دهد با استفاده از زبان های مختلف با هم ایجاد شوند. برنامه های ما با دات نت به نام زبان میانی (IL) کامپایل شده اند.

کد مدیریت شده و مدیریت نشده

قبل از شروع به یادگیری کمی بیشتر در مورد CLR و IL، باید مفاهیم کد مدیریت شده و مدیریت نشده را بدانیم، این مهم است که برجسته کنیم زیرا یکی از هر دو روشی است که برنامه های ما در سیستمی که روی آن نصب شده اند اجرا می شوند. مقدر شده است.

کد مدیریت شده

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

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

این محیط اجرا به طور رسمی تر به عنوان یک ماشین مجازی یا برنامه کاربردی شناخته می شود که به اختصار PVM (ماشین مجازی در سطح فرآیند) شناخته می شود، که به عنوان هر برنامه کاربردی در سیستم اجرا می شود و از یک فرآیند فردی و مستقل در سیستم عامل پشتیبانی می کند، بنابراین به زبان هایی اجازه می دهد که در آنها استفاده شود. برنامه‌های ما نوشته شده‌اند و با سیستم ارتباط برقرار می‌کنند و واسطه‌ای بین زبان و کد ماشین هستند.

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

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

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

این کدی است که مستقیماً در سیستم عامل اجرا می شود، یعنی هیچ محیط اجرایی یا ماشین مجازی میانی برای اجرا وجود ندارد، بنابراین، این وظیفه توسعه دهنده است که منابعی را که برنامه های خود به آنها دسترسی دارند مدیریت کند تا کارآمد باشند آنها تمایل دارند عملکرد بالاتری نسبت به آنها با کد مدیریت شده داشته باشند زیرا این لایه میانی وجود ندارد و بنابراین فرآیند تفسیر، کامپایل یا تبدیل کد به کد ماشین در طول زمان اجرا وجود ندارد. برنامه‌هایی که به زبان‌هایی نوشته می‌شوند که مستقیماً در کد ماشین مانند C یا C++ کامپایل می‌شوند، نمونه‌هایی از کدهای مدیریت‌نشده هستند، اگرچه به این معنی نیست که ما نمی‌توانیم کدهایی را در C# بنویسیم، مثلاً بدون مدیریت.

بهترین گزینه چیست؟

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

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

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

اگر به دلیل ماهیت پروژه، استفاده از کد مدیریت شده 100٪ غیرممکن است، ممکن است توصیه شود که هر دو طرح را ترکیب کنید: اجزایی که به آن نیاز دارند به عنوان کد مدیریت نشده توسعه داده می شوند و بقیه به عنوان کد مدیریت شده پیاده سازی می شوند.

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

کد مدیریت شده در مقابل کد غیر مدیریتی

زمان اجرا زبان رایج (CLR)

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

اگر به زبان سی شارپ برنامه نویسی کنیم، CLR، جاوا JVM (ماشین مجازی جاوا) است که بین هر دو پلتفرم پل ارتباطی برقرار می کند و بهترین و نزدیک ترین مثال در این زمینه است، زیرا هدف آن تفسیر، کامپایل یا ترجمه کد میانی است. بین زبان و کد ماشین

از طرف مایکروسافت، آنها به CLR به عنوان یک محیط زمان اجرا مدیریت شده اشاره می کنند که در آن برنامه های نوشته شده به هر یک از زبان های پلت فرم مانند ویژوال بیسیک، سی شارپ یا F# پس از کامپایل شدن به زبان میانی می توانند در CLR اجرا شوند. هنگامی که کد خود را به هر یک از این زبان ها می نویسید، نسخه ای از محیط را برای استفاده و کامپایل ایجاد می کنید، کاری که واقعا انجام می دهید ایجاد اطلاعات توصیفی در مورد برنامه ای است که در برنامه کامپایل شده به عنوان ابرداده ذخیره می شود، این ابرداده در فایل ها exe من dll بیشتر به عنوان اسمبلی شناخته می شود، که در یک زبان میانی و بهینه سازی شده برای اجرا خواهد بود، تمام این اطلاعات به CLR زبانی که برنامه در آن نوشته شده است، نسخه، کتابخانه های کلاس، مراجع و هر چیزی که برنامه برای اجرای خود نیاز دارد، می گوید. به عنوان یک برنامه کاربردی مستقل شناخته می شود که همه چیز لازم برای اجرای آن را در هر ماشینی با محیط اجرا نصب شده دارد.

به این ترتیب، CLR به برنامه های شما اجازه می دهد که مثلاً یک شیء نمونه سازی شده از کلاسی که به یک زبان نوشته شده است، بتواند متد کلاس دیگری را که به زبان دیگری نوشته شده است فراخوانی کند.

توابع CLR

  • مدیریت حافظه از طریق Garbage Collector.
  • رسیدگی به استثنا
  • ایمنی را تایپ کنید
  • امنیت بین فرآیندها
  • مدیریت کدهای در حال اجرا

اجزای CLR

  • Compilador JIT (تدوین به موقع).
  • کلاس لودر.
  • استخر نخ.

جریان تدوین پروژه در دات نت

زبان متوسط ​​(IL)

همچنین به عنوان زبان میانی مایکروسافت (MSIL در بتای زبان‌های دات‌نت) یا زبان متوسط ​​معمولی (CIL) شناخته می‌شود، این کد تولید شده از فرآیند کامپایل برنامه ما است که به زبان انتخابی ما بر روی پلتفرم بدون توجه به این‌ها نوشته می‌شود. است.

زبان متوسط ​​کدی است که سطح انتزاعی پایین تری نسبت به زبان هایی مانند C# یا F# (زبان های سطح بالا) دارد که نوشتن، خواندن و مدیریت آن را برای توسعه دهندگان کمی دشوارتر می کند، اما سطح آن از کد ماشین بالاتر است. خود

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

نمونه کدهای IL

چیزی که مایکروسافت از طریق زبان میانی به دنبال آن است این است که ما این آزادی را داریم که هر زبانی را که توسط پلتفرم و برنامه دات نت پشتیبانی می شود در این زبان بدون نگرانی در مورد نحوه اجرای آن، علاوه بر داشتن توانایی استفاده از این زبان ها، انتخاب کنیم. با هم برنامه های خود را ایجاد کنیم. این امر با ایجاد زبان میانی با پیروی از مشخصات باز و استاندارد فنی شناخته شده به عنوان زیرساخت زبان مشترک (CLI) به دست آمد، بنابراین به برنامه‌های نوشته شده به هر زبانی اجازه می‌دهد با یکدیگر کار کنند و بر روی انواع مختلف سخت‌افزار اجرا شوند. CLI به نوبه خود شامل سیستم نوع مشترک (CTS) و مشخصات زبان مشترک (CLS) است.

برخی از پیاده سازی های CLI عبارتند از .NET Framework، .NET (یا NET Core) و Mono.

زبان های دات نت، IL، CLR و کد بومی

کنجکاوی در مورد CLR و IL

آیا کامپایل JIT توسط CLR برای هر متد، هر بار که فراخوانی می شود، اجرا می شود؟

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

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

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

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

با ژنریک چه اتفاقی می افتد؟

ژنریک ها در دات نت رفتار خاصی در رابطه با کامپایل JIT دارند، زیرا CLR کامپایل آنها را بسته به نوع نمونه سازی آنها به روشی بهینه مدیریت می کند، یعنی اینکه آیا آنها از نوع ارزش (انواع ارزش) یا نوع مرجع هستند ( انواع مرجع) که در زیر توضیح داده شده است:

  • هنگامی که یک نوع عمومی با یک نوع مقدار (مثلاً int، float، structو غیره)، CLR یک نسخه خاص از روش عمومی را برای هر نوع مقداری که با آن نمونه سازی شده است، جمع آوری می کند. این به این دلیل است که انواع مقادیر در دات نت دارای اندازه و نمایش متفاوتی در حافظه هستند، بنابراین کد تولید شده باید برای هر نوع مقدار منحصر به فرد باشد.

    • به عنوان مثال، کلاس عمومی List شما از آن استفاده می کنید List y List، CLR دو بیلد متفاوت تولید می کند، یکی برای int و دیگری برای double.

    این به این دلیل اتفاق می‌افتد که انواع مقادیر مستقیماً در حافظه ذخیره می‌شوند و کامپایل‌های خاص نحوه مدیریت آن مقادیر را بهینه می‌کنند.

  • هنگامی که یک نوع عمومی با یک نوع مرجع (مثلاً string، object، یا هر کلاسی که توسط شما تعریف شده باشد)، CLR یک نسخه کامپایل شده را برای همه انواع مرجع به اشتراک می گذارد. یعنی کامپایل JIT یک بار برای همه انواع مرجع انجام می شود، زیرا این انواع همیشه توسط مراجع (اشاره گرها یا آدرس های حافظه) هدایت می شوند و نمایش درون حافظه برای همه انواع مرجع یکنواخت است.

    • مثلا اگر استفاده می کنید List y List، CLR یک نسخه واحد را برای انواع مرجع کامپایل می کند و از آن برای هر دو مورد استفاده مجدد می کند.

آیا هنگام استفاده از Reflection، کد کامپایل شده توسط JIT نیز در حافظه ذخیره می شود؟

در مورد استفاده از Reflection در دات نت برای فراخوانی متدها، چه عمومی و چه غیر عمومی، کد با استفاده از JIT کامپایل شده و در حافظه ذخیره می شود:

  • وقتی روشی را با استفاده از Reflection فراخوانی می‌کنید، CLR همچنان باید روش را از IL به کد ماشین با استفاده از JIT کامپایل کند. این به همان صورت اتفاق می افتد که اگر متد مستقیماً در کد فراخوانی شده باشد.
  • هنگامی که متد JIT کامپایل شد، کد به دست آمده برای استفاده مجدد در فراخوانی های بعدی در حافظه ذخیره می شود، حتی اگر متد از طریق Reflection فراخوانی شده باشد.

JIT اولین باری که فراخوانی می شود متد را کامپایل می کند و کد بومی را در حافظه ذخیره می کند، بنابراین اگر همان روش را دوباره با Reflection فراخوانی کنید، CLR از کد کامپایل شده مجددا استفاده می کند و از کامپایل مجدد آن اجتناب می کند.

عملاً آنچه تغییر می کند نحوه فراخوانی متد است که اگر متد را از کد خود به روش معمولی فراخوانی کنید ثابت یا مستقیم است و پویا یا غیرمستقیم است که وقتی از Reflection اسکن متادیتای انواع استفاده می کنید تا متد را پیدا کنید و آن را اجرا کنید. ; برای CLR مهم نیست که چگونه آن را اجرا می کنید، تنها چیزی که مهم است این است که شما آن را اجرا می کنید و آن را به کد بومی یا ماشینی کامپایل می کند، با این حال، به خاطر داشته باشید که استفاده از Reflection بر عملکرد تأثیر می گذارد، اما این چیزی برای این کار را با CLR انجام دهید، بلکه با استفاده از بازرسی نوع و کشف نوع در زمان اجرا با استفاده از Reflection انجام دهید.

به این ترتیب، هنگامی که متد به کد بومی کامپایل شد، هم برای فراخوانی مستقیم و هم برای فراخوانی با Reflection، کد کامپایل شده ذخیره شده و مجددا استفاده می شود. این بدان معنی است که فرآیند ساخت خود تکرار نمی شود، اما بخش پویا فراخوانی از طریق Reflection (جستجو و فراخوانی) همچنان کندتر است زیرا همیشه انجام خواهد شد.

منابع اضافی

https://www.geeksforgeeks.org/common-language-runtime-clr-in-c-sharp/

https://en.wikipedia.org/wiki/Common_Intermediate_Language

https://www.artima.com/articles/clr-design-choices

https://snifftontechnologies.wordpress.com/2014/03/05/what-is-common-language-runtime-in-c/

نوشته های مشابه

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا