PDA

View Full Version : مقاله: Native Image Generator - Ngen.exe



Amir Oveisi
یک شنبه 20 مرداد 1387, 18:10 عصر
Native Image Generator - Ngen.exe

Native Image Generator یکی از ابزارهای .NET Framework‌ برای بهبود کارایی managed application ها می باشد. Ngen.exe یک native image ایجاد می کند که شامل کد های ماشین پیش کامپایل شده و processor-specific بوده و آن ها را در native image cache کامپیوتر نصب می کند. از این رو runtime می تواند به جای استفاده از کامپایلر JIT برای کامپایل assembly مورد نظر، از این native image موجود در cache‌ استفاده کند.
Ngen.exe برای یک assembly ‌مشخص شده و کلیه dependency های آن native image ایجاد می کند. این dependency ها از روی reference های موجود در فایل manifest مربوط به assembly انتخاب شده شناسایی می شوند. تنها زمانی نیاز به ایجاد native image‌ مجزا برای یک dependency وجود دارد و آن هم زمانی است که از متد Assembly.Load در برنامه استفاده شده است که در این صورت باید این Assembly بصورت جداگانه در native image cache‌ بار شود.
توجه داشته باشید که در صورت استفاده از متد Assembly.LoadFrom در برنامه، آن image‌ که توسط این متد در native image cache‌ بار می شود توسط assembly های دیگر در حال اجرا قابل استفاده نخواهد بود.
Ngen.exe همیشه تعداد dependency ها را می داند و آن ها را نگهداری می کند. به عنوان مثال، فرض کنید که myAssembly.exe و yourAssembly.exe هر دو در native image cache بارگذاری شده اند و هر دوی ان ها دارای یک reference‌به اسم ourDependency.dll می باشند. حال اگر myAssembly.exe از native image cache پاک (uninstall) شود، ourDependency.dll هنوز در native image cache‌ باقی خواهد ماند و تا زمانی که yourAssembly.exe نیز uninstall نشود، ourDependency.dll‌ نیز uninstall‌ نخواهد شد.

چه زمانی از Native Image ها استفاده کنیم؟
Native image ها می توانند به دو طریق باعث بهبود کارایی شوند:
1- استفاده بهینه حافظه
2- کاهش زمان startup
توجه داشته باشید که کارایی native image ها به فاکتورهای زیادی بستگی دارد که تحلیل آن را دشوار می کند، مانند وابستگی به کد، الگوهای دسترسی به داده ها، تعداد فراخوانی بین module های مختلف و تعداد dependency هایی که توسط سایر application ها بارگذاری شده اند. تنها راه دقیق برای مشخص کردن اینکه استفاده از native image سبب بهبود کارایی خواهد شد یا خیر، سنجش دقیق کارایی application‌ تان می باشد.

استفاده بهینه از حافظه

Native image‌ ها می توانند بطور قابل توجهی مصرف حافظه را بهبود بخشند. Native image ها، فایل های Windows PE‌ هستند بنابراین یک کپی از یک فایل .dll می تواند بین چندین process به اشتراک گذاشته شود. بر خلاف این موضوع، native code تولید شده توسط JIT در private memory نگهداری می شود و قابلیت به اشتراک گذاشته شدن را ندارد.
همچنین application هایی که تحت Terminal service اجرا می شوند نیز می توانند از image‌های به اشتراک گذاشته شده بهره ببرند.
علاوه بر این، load‌ نکردن کامپایلر JIT، فضای ثابتی از حافظه را برای هر نمونه از Application آزاد نگه می دارد و به این ترتیب باز در مصرف حافطه صرفه جویی می شود.

افزایش سرعت Startup

پیش-کامپایل کردن assembly ها توسط Ngen.exe می تواند سبب کاهش زمان Startup شود. این مسئله زمانی میسر خواهد بود که application ها Assembly های خود را یه اشتراک بگذارند،‌زیرا پس از اولین startup، هنوز assembly ها در native image cache وجود دارند و برای استفاده های بعدی آماده اند. در حالی که در Cold Startup ها، که همه Assembly ها در هر بار اجرا از hard disk خوانده شده و توسط JIT‌ کامپایل می شوند، سرعت startup بسیار کاهش می یابد زیرا سرعت خواندن اطلاعات از hard disk بسیار پایین است.

Native Image ها و JIT

پس از ایجاد یک native image‌ برای یک Assembly، در هر بار اجرا،‌ runtime بصورت اتوماتیک سعی خواهد کرد تا native image مربوطه را یافته و از آن استفاده کند. اگر زمانی runtime قادر به یافتن قسمتی از Assembly در native image cache نباشد، آن قسمت توسط JIT کامپایل شده و استفاده می شود. توجه داشته باشید که این عمل سبب ترمیم native image آن Assembly نخواهد شد و برای این منظور باید دوباره یک image جدید ایجاد شود.

چند مثال از کاربرد Ngen.exe



ngen install ClientApp.exe
این کد در command prompt سبب ایجاد یک native image برای ClientApp.exe و بار کذاری آن در native image cache‌ می شود. در اینجا ClientApp.exe در دایرکتوری جاری قرار دارد.



ngen install c:\myfiles\MyAssembly.exe



ngen display
نشان دادن کلیه image های موجود در native image cache



ngen display c:\myApps\MyAssembly.exe
نشان دادن image مربوط به assembly مشخص شده.



ngen uninstall ClientApp
برای پاک کردن (uninstall) یک image از native image cache

برای مشاهده لیست کامل دستورات به MSDN مراجعه شود.

Ngen.exe و امنیت کد

لازم به ذکر است که native image‌های ایجاد شده توسط Ngen.exe دارای فرمت فایل خاص بوده و قابل استفاده بصورت جداگانه نمی باشند. از این رو نمی توان از Ngen.exe به عنوان ابزاری برای تولید native code برای .NET Assembly نام برد.
با استفاده از دستور dumpbin.exe می توان آدرس native image های تولید شده توسط Ngen.exe‌ را بدست آورد. به عنوان مثال:


Dumpbin c:\myApp.exe

این دستور نتیجه ای به شکل زیر خواهد داشت:



File Type: EXECUTABLE IMAGE
Summary
2000.reloc
2C000.rsrc
DA000.text

ملاحظه می کنید که هر image موجود در native image cache بصورت dump سه فایل با فرمت های .reloc و .rsrc و .text می باشد و قابل استفاده بصورت مجزا نمی باشند.

منبع :‌ MSDN

امیر اویسی bermooda_Star@yahoo.com 20/5/1387

jalalx
چهارشنبه 30 تیر 1389, 16:18 عصر
ممنون از مقاله خوبتون! :قلب:
اگر از منظر کاربردی به قضیه نگاه کنیم، چطور می شه ازش استفاده کرد. مثلا اگه بخوایم start up برنامه سریع باشه باید این کار رو چطوری رو سیستم مقصد (کاربر نهایی) انجام بدیم؟ تو setup سازی چه کار کنیم؟ آیا با کد نویسی می شه این کار رو کد؟ یا با کاربر تماس بگیریم بگیم همچین کاری بکن :بامزه:!

ببخشید بعد 2 سال پستو اوردم بالا که یه سوال بپرسم!!! :لبخند:

Esmail Solhkhah
جمعه 20 بهمن 1391, 10:49 صبح
ممنون از مقاله خوبتون! :قلب:
اگر از منظر کاربردی به قضیه نگاه کنیم، چطور می شه ازش استفاده کرد. مثلا اگه بخوایم start up برنامه سریع باشه باید این کار رو چطوری رو سیستم مقصد (کاربر نهایی) انجام بدیم؟ تو setup سازی چه کار کنیم؟ آیا با کد نویسی می شه این کار رو کد؟ یا با کاربر تماس بگیریم بگیم همچین کاری بکن :بامزه:!

ببخشید بعد 2 سال پستو اوردم بالا که یه سوال بپرسم!!! :لبخند:

با استفاده از
RuntimeEnvironment.GetRuntimeDirectory (http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.runtimeenvironment. getruntimedirectory.aspx)
مسیر CLR و از اونجا ngen.exe رو بدست بیارید.
با استفاده از Process (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx) اسمبلی مورد نظر رو به ngen پاس کنید.

یه متد نمونه :


public static void CreateNativeImages(string[] assemblies)
{
string path = Path.Combine(RuntimeEnvironment.GetRuntimeDirector y(), "ngen.exe");
if (File.Exists(path))
{
foreach (string str2 in assemblies)
{
ProcessStartInfo startInfo = new ProcessStartInfo(path, str2) {
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath)
};
Process.Start(startInfo).WaitForExit();

}
}
else
{
MessageBox.Show("File ngen.exe is not found.");
}
}

ببخشید بعد 2 سال پستو بالا آوردم، هدف آشنایی دوستانی هست که همچین سوالی دارن.

موفق باشید.