زمانیکه اولین نگارش ASP.NET حدود 10 سال قبل منتشر شد، تنها سیستم عاملی که از آن پشتیبانی میکرد، ویندوز سرور 2000 بود، تنها پروسهی اجرایی آن aspnet_wp نام داشت و تنها معماری پشتیبانی شده هم X86 بود. به پروسهی aspnet_wp محدودیت مصرف حافظهای اعمال شده بود که در حین آغاز آن بر اساس مقدار قابل تغییر
processModel memoryLimit محاسبه و اعمال میشد (تعریف شده در فایل ماشین کانفیگ). این عدد به صورت درصدی از ظرفیت RAM فیزیکی سیستم، قابل تعریف و به صورت پیش فرض به 60 درصد تنظیم شده بود. به این ترتیب این پروسه مجاز نبود تا تمام حافظهی فیزیکی مهیا را مصرف کند و در صورت وجود نشتی حافظهای در برنامهای خاص، این پروسه امکان بازیابی مجدد حافظه را پیدا میکرد (recycling). همچنین یک مورد دیگر را هم باید در نظر داشت و آن هم وجود قابلیتی است به نام ASP.NET Cache است که امکان ذخیره سازی مقادیر اشیاء را در حافظهی مصرفی این پروسه مهیا میسازد. هر زمان که میزان این حافظهی مصرفی به حد نزدیکی از محدودیت تعریف شده برسد، این پروسه به صورت خودکار شروع به حذف آنها خواهد کرد.
محدودیت 60 درصدی تعریف شده، برای سیستمهایی با میزان RAM کم بسیار مفید بود اما در سیستمهایی با میزان RAM بیشتر، مثلا 4 گیگ به 2.4GB حافظه مهیا (60 درصد حافظه فیزیکی سیستم) محدود میشد و همچنین باید در نظر داشت که میزان user mode virtual address space مهیا نیز تنها 2 گیگابایت بود. بنابراین هیچگاه استفاده مؤثری از تمام ظرفیت RAM مهیا صورت نمیگرفت و گاها مشاهده میشد که یک برنامه تنها با مصرف 1.5GB RAM میتوانست پیغام OutOfMemoryException را صادر کند. در این حالت مطابق بررسیهای صورت گرفته مشخص شد که اگر مقدار processModel memoryLimit به حدود 800 مگابایت تنظیم شود، بهترین عملکرد را برای سیستمهای مختلف میتوان مشاهده کرد.
با ارائهی ویندوز سرور 2003 و همچنین ارائهی نسخهی 1.1 دات نت فریم ورک و ASP.NET ، این وضعیت تغییر کرد. پروسهی جدید در اینجا w3wp نام دارد و این پروسه تعاریف مرتبط با محدودیت حافظهی خود را از تنظیمات IIS دریافت میکند (قسمت Maximum Used Memory در برگهی Recycling مربوط به خواص Application Pool مرتبط). متاسفانه این عدد به صورت پیش فرض محدودیتی ندارد و به ظاهر برنامه مجاز است تا حد امکان از حافظهی مهیا استفاده کند. به همین جهت یکی از مواردی را که باید در نظر داشت، مقدار دهی Maximum Used Memory ذکر شده است. خصوصا اینکه در نگارش 1.1 ، تنظیمات میزان مصرف RAM مرتبط با ASP.NET Cache نیز با برنامه یکی است.
در نگارش 2.0 دات نت فریم ورک، تنظیمات مرتبط با ASP.NET cache از تنظیمات میزان RAM مصرفی یک برنامهی ASP.NET جدا شد و این مورد توسط قسمت cache privateBytesLimit قابل تنظیم و مدیریت است (در فایل IIS Metabase و همچنین فایل web.config برنامه).
نکته!
اگر process memory limit و همچنین cache memory limit را تنظیم نکنید، باز به همان عدد 60 درصد سابق بازخواهیم گشت و این مورد به صورت خودکار توسط IIS محاسبه و اعمال میشود. البته محدودیت ذکر شده برای پروسههای 64 بیتی در این حالت بسیار بهتر خواهد بود. اگر هر دوی اینها را تنظیم کنید، عدد حداقل بکارگرفته شده، مبنای کار خواهد بود و اگر تنها یکی را تنظیم کنید ، این عدد به هر دو حالت اعمال میگردد. برای بررسی بهتر میتوان به مقدار Cache.EffectivePrivateBytesLimit و Cache.EffectivePercentagePhysicalMemoryLimit مراجعه کرد.
و ... اکنون بهتر میتوانید به این سؤال پاسخ دهید که «سرور ما بیشتر از 4 گیگ رم دارد و برنامهی ASP.NET من الان فقط 850 مگ رم مصرف کرده (که البته این هم نشانی از عدم dispose صحیح منابع است یا عدم تعیین تقدم و تاخر و زمان منقضی شدن، حین تعریف اشیاء کش)، اما پیغام out of memory exception را دریافت میکنم. چرا؟!»
بنابراین ایجاد یک
Application pool جدید به ازای هر برنامهی ASP.NET امری است بسیار مهم زیرا:
- به این ترتیب هر برنامهی ASP.NET در پروسهای ایزوله از پروسهی دیگر اجرا خواهد شد (این مساله از لحاظ امنیتی هم بسیار مهم است). در اینجا هر برنامه، از پروسهی w3wp.exe مجزای خاص خود استفاده خواهد کرد (شبیه به مرورگرهایی که هر tab را در یک پروسه جدید اجرا میکنند).
- اگر پروسهای به حد بالای مصرف حافظهی خود رسید با تنظیمات انجام شده در قسمت recycling مرتبط با Application pool اختصاصی آن، به صورت خودکار کار بازیابی حافظه صورت میگیرد و این امر بر روی سایر برنامهها تاثیر نخواهد داشت (کاربران سایر برنامهها مدام شکایت نمیکنند که سشنها پرید. کش خالی شد. زیرا در حالت وجود application pool اختصاصی به ازای هر برنامه، مدیریت حافظه برنامهها از هم ایزوله خواهند بود)
- کرش صورت گرفته در یک برنامه به دلیل عدم مدیریت خطاها، بر روی سایر برنامهها تاثیر منفی نخواهد گذاشت. (زمانیکه ASP.NET worker process به دلیل استثنایی مدیریت نشده خاتمه یابد بلافاصله و به صورت خودکار مجددا «وهلهی دیگری» از آن شروع به کار خواهد کرد؛ یعنی تمام سشنهای قبلی از بین خواهند رفت؛ که در صورت ایزوله سازی ذکر شده، سایر برنامهها در امان خواهند ماند؛ چون در پروسه ایزولهی خود مشغول به کار هستند)
- با وجود application pool اختصاصی به ازای هر برنامه، میتوان برای سایتهای کم ترافیک و پرترافیک، زمانهای recycling متفاوتی را اعمال کرد. به این ترتیب مدیریت حافظهی بهتری قابل پیاده سازی میباشد. همچنین در این حالت میتوان مشخص کرد کدام سایت از تعداد worker process بیشتر یا کمتری استفاده کند.
- کاربری که پروسهی ASP.NET تحت آن اجرا میشود نیز همینجا تعریف میگردد. بنابراین به این ترتیب میتوان به برنامهای دسترسی بیشتر و یا کمتر داد، بدون تاثیر گذاری بر روی سایر برنامههای موجود.
نتیجه گیری:
- از IIS استفاده میکنید؟ آیا میدانید Application pool چیست؟
- آیا میدانید در صورت عدم مقدار دهی پارامترهای حافظهی یک Application pool ، به صورت پیش فرض چند درصد از حافظهی فیزیکی مهیا در اختیار شما است؟
برای مطالعه بیشتر: