CLR چیست؟
#1
Note 
(Common Language Runtime)CLR

یک موتور اجرایی است که با هدف اصلی اجرای هدایت شده کدها در .Net ایجاد گردیده است. CLR به مدیریت اجرا، ارتقای نسخه و امنیت تمامی کدها در .Net می پردازد. به همین دلیل کدهای .Net یا C# اغلب تحت عنوان کدهای مدیریت شده، شناخته می شوند.(Managed Code) تمامی کدهایی که به CLR مرتبط هستند، تحت عنوان "مدیریت شده" و کدهایی توسط CLR مدیریت نشده اند، بلکه مستقیماً به کد ماشین تبدیل می شوند، تحت عنوان "مدیریت نشده" بیان می شوند.



کدهای مدیریت شده، به کد ماشین کامپایل نمی شوند، بلکه به زبان سطح میانی مایکروسافت(MSIL) کامپایل شده و مورد استفاده قرار می گیرند. این زبان سطح میانی را می توان زبانی شبیه به زبان اسمبلی تصور کرد. IL در حافظه بارگذاری می شود و بلافاصله بوسیلة CLR در حافظه به کد ماشین کامپایل می گردد.

[تصویر:  2.jpg]

برنامه های .Net از اسمبلی هایی تشکیل شده اند که اجزای خودکار منطقی توسعه، شناسایی و امنیت به حساب می آیند و تفاوت آنها با روشهای قدیمی در آن است که اسمبلی می تواند شامل یک یا چندین فایل باشد. اسمبلی .Net به صورت یک فایل اجرایی تک یا یک فایل کتابخانه ای است، اما ممکن است حاوی ماژول ها، که کدهایی غیر اجرایی بوده و قابلیت استفادة مجدد را دارند، نیز باشد.

مسئلة مهم دیگر در مورد CLR، نحوة بارگذاری(Load) و اجرای برنامه توسط آن است. به محض اینکه برنامة .Net شروع به اجرا می کند، ویندوز اسمبلی .Net راتشخیص داده و CLR را اجرا می کند. سپس CLR نقطه شروع برنامه را شناسایی و پروسة تعیین انواع که در آن، محل قرارگیری انواع مختلف بکار رفته در برنامه مشخص می شود را، اجرا می کند. اسمبلی شناسایی شده در پروسة Loader بارگذاری می گردد.

در ویژوال بیسیک 6 و کلا ً سیستم های قبلی که بر COM استوارند نسخه یک COM مساله بزرگی برای انتشار آن است. در حالی که شما می توانستید نسخه های مختلفی از یک COM داشته باشید ولی در استفاده از ProgID ها دارای محدودیت بودید. برای مثال در ویژوال بیسیک هنگام استفاده از Word.Application نمی توانستید نسخه آن را انتخاب کنید، یعنی برای مثال Word.Application.9. در CLR تمام اجزا در GAC یا Global Assemblies Cache بار می شوند. بعبارت دیگر اطلاعات اسمبلی ها در GAC قرار می گیرند. در CLR دو ویژگی برای اسمبلی هایی که در GAC قرار می گیرند وجود دارد:



Side-by-side versioning: بدین معنی که نسخه های مختلف یک اسمبلی در کنار هم بدون تداخل وجود دارند.



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



نسخه ها در CLR از چهار قسمت Major.Minor.Revision.Build تشکیل شده اند. اگر در Major و Minor تغییری داده شود، این بدین معناست که این نسخه از اسمبلی دیگر با نسخه های قبلی سازگاری ندارد.



انتقال:
برنامه هایی که به زبان ویژوال بیسیک قدیمی نوشته می شوند در هنگام انتقال به کامپیوترهای دیگر دچار مشکلات فراوان می شوند. تمامی اجزا باید در رجیستری ثبت شوند. اگر نسخه جدیدی ایجاد شود امکان دارد برنامه هایی که از نسخه قدیمی استفاده می کردند را از کار بیندازد. ولی درNET. هم مساله نسخه ها تقریبا ً حل شده است و هم نحوه انتقال. کافی است در کامپیوتر مقصد NET Framework. نصب شده باشد. در این صورت به راحتی با استفاده از دستور xcopy داس می توانید برنامه خود را انتقال بدهید!



شایان ذکر است که این نوشته صرفا ً توضیح مختصری درباره هر کدام از قسمت های NET. می دهد و برای هر کدام از این اجزا می توان یک مقاله مفصل نوشت.



مدیریت حافظه:
درباره مدیریت حافظه CLR بیشتر در زمینه VB بحث می کنیم.

مدیریت بهتر بر Garbage Collection:
Runtime در ویژوال بیسیک دارای سیستم خود کار برای Garbage Collection ها است. در ویژوال بیسیک 6، runtime به شکل خودکار منابع را از شئ هایی که دیگر توسط برنامه استفاده نمی شوند می گیرد. برای مثال فرض کنید می خواهیم یک فایل LOG ایجاد کنیم، برای این کار می توان از دو شئ Scripting.Stream و Scripting.FileSystemObject استفاده کرد. اگر این دو شئ را در تابعی به کار ببریم، بعد از اتمام عملیات، runtime منابع اختصاص داده شده به این دو شئ را می گیرد. اما مواردی وجود دارد که runtime به آسانی امکان تشخیص شئ و زمان بلااستفاده بودن آن را ندارد.



Cyclical References:
یکی از مهمترین زمانهایی که runtime مربوط به VB نمی تواند تشخیص بدهد که آیا یک شئ به منابعی احتیاج دارد یا اینکه کارش به پایان رسیده زمانی است که در متن برنامه حالتی به نام Cyclical Reference بوجود بیاید. به عنوان مثال اگر شئ A به صورت reference از شئ B استفاده کند و همچنین شئ B از A.



هر شئ COM مسئول نگهداری تعداد دفعاتی است که فعال شده است. بدین صورت که هر بار از روی آن ساخته شود با AddRef و هربار که یک برنامه آن را رها کند با Release از IUnKnown interface شمارنده ای را یکی افزایش یا کاهش می دهد. اگر آن شمارنده به صفر برسد شئ تمامی منابع خود را آزاد می کند، اما اگر هنگامی که یک شئ COM غیر فعال شود ولی از Release استفاده نشود یک شئ بلا استفاده در حافظه می ماند.



runtime مربوط به VB 6 این کار را به صورت خودکار انجام می دهد، اما هنگامی که دو شئ به هم اشاره می کنند بحث فرق می کند و runtime به شکل حالت ساده نمی تواند یک شئ را از حافظه بردارد. برای مثال به قطعه برنامه زیر توجه کنید.
کد:
'Class : CCyclicalRef



Dim m_objRef as Object



Public Sub Initialize(objRef as Object)
    Set m_objRef = objRef
End Sub



Private Sub Class_Terminate()
    Call Msgbox("Terminating.")
    Set m_objRef = Nothing
End Sub



در کلاس CCyclicalRef متدی با نام Initialize تعریف شده است که در پارامتر های خود یک شئ را می پذیرد و از روی آن یک شئ دیگر می سازد. حال از کلاس تعریف شده در کد زیر استفاده می کنیم.
کد:
Dim objA as New CCyclicalRef
Dim objB as New CCyclicalRef



Call objA.Initialize(objB)
Call objB.Initialize(objA)



Set objA = Nothing
Set objB = Nothing

ابتدا دو نمونه از روی کلاس CCyclicalRef با نامهای objA و objB ساختیم، حال هر دوی این شئ ها یک بار ساخته شده اند و شمارنده آنها یک است. با استفاده از متد Initialize هر دوی شئ ها، آدرس حافظه یکدیگر را مبادله می کنند و به این شکل از روی هر دوی آنها یک بار دیگر ساخته می شود و شمارنده هر دو، 2 می شود. شماره یک مربوط به خود برنامه است و شماره دوم مربوط به شئ هایی که به هم اشاره می کنند. سپس هر دوی آنها را برابر nothing قرار می دهیم تا آنها را از حافظه حذف کنیم. در اینجا شمارنده هر دو یکی کم و برابر یک می شود. بنابراین برنامه terminate شده است ولی هنوز شئ در حافظه وجود دارد.



Garbage Collector در CLR:
روش Garbage Collector در CLR با VB 6 Runtime تفاوت دارد. در روش جدید که خود ِ CLR و GC مسئول اجرای آن هستند، آخرین باری که از nothing استفاده می شود ولی هنوز شئ در حافظه مانده باشد، GC این وضعیت را درک می کند و آن شئ را بعد از مدتی از حافظه خارج می کند. شئ هایی هستند که مانند COM مسئول غیر فعال کردن خود نیستند، GC آنها را نیز تشخیص داده و اگر برنامه ای دیگر از آنها استفاده نکند، از حافظه حذف می شوند.



Finalize:
GC متد Object.Finilize را قبل از اینکه هر شئ را از حافظه حذف کند صدا می زند. این متد می تواند در هر زمانی بعد از اینکه برنامه دیگر از شئ استفاده نکرد صدا زده شود، لذا در هنگام استفاده از این متد باید نکته را در نظر گرفت. درNET. بهتر است قبل از اینکه یک شئ بوسیله nothing از بین برود از متد Dispose یا Close استفاده شود تا سریعا ً از حافظه حذف شود.



روش سریعتر تخصیص حافظه به شئ ها
هر زمان که یک برنامه یک شئ بسازد حافظه ای به آن اختصاص می یابد، آن حافظه در virtual memory است که برای هر برنامه اختصاص می یابد و به آن heap گفته می شود. CLR مفهومی به نام Managed Heap دارد بدین معنی که شئ ها را مدیریت می کند و آنها را در یک Heap ِ مدیریت شده قرار می دهد و CLR مسئول حفاظت آنهاست.



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



ابتدا CLR حافظه ای برای شئ های A، B و C بر روی Heap در نظر می گیرد. سپس شئ B از حافظه حذف می شود، در ادامه نیز برنامه یک شئ دیگری به نام D می سازد و آن را بر روی آخرین شئ‎ای که ساخته شده بود یعنی C قرار می دهد. این روش برای اختصاص حافظه سریع است. اما اگر CLR به انتهای heap برسد چه عملی باید انجام دهد؟ همان طور که مشاهده کردید این روش به شکل افزایشی شئ ها را در حافظه قرار می دهد. وقتی CLR دیگر نتواند از حافظه استفاده کند GC را فرا می خواند. GC هم فضاهایی مانند B را کاملا ً آزاد می کند و هم شئ ها را فشرده می کند و در پایین heap قرار می دهد تا بالای heap آزاد باشد.

pardisanus.persianblog.ir

پاسخ
ایجاد موضوع جدید   پاسخ به موضوع  

موضوعات مرتبط با این موضوع...
موضوع نویسنده پاسخ بازدید آخرین ارسال
Note Garbage Collector چیست؟ SOFTAFZAR 0 1,223 01-12-2012 ساعت 11:15
آخرین ارسال: SOFTAFZAR

کاربرانِ درحال بازدید از این موضوع:   1 مهمان