مدیریت حافظه – انجمن DEV

هنگامی که با مدیریت حافظه در دات نت سروکار دارید، جمع آوری زباله به عنوان چیزی به ذهن می رسد که باید دائماً آن را نظارت کنید. درک نحوه تعامل برنامه شما با زباله جمع کن تفاوت ایجاد می کند.
تخصیص حافظه
ویندوز چگونه هیپ و تخصیصهای جدید را مدیریت میکند و فهرست اسلاتهای رایگان را برای کاهش تکه تکه شدن حفظ میکند، با برنامههای کد بومی همیشه این گزینه را دارید که تخصیص حافظه را تا حد امکان خطی با یا بدون طرح تخصیص سفارشی حفظ کنید. در حافظه دات نت، بخش ها کنترل می شوند، بنابراین اشیاء در نزدیکی یکدیگر قرار می گیرند.
بنابراین هنگام تخصیص یک شی، مقدار تخصیص آن به اطلاعات بافر تنظیم میشود که به دنبال بایت بعدی موجود میگردد و آن را با انتهای بافر تخصیص مقایسه میکند و به دنبال فضایی است که شی جا میگیرد، پس همیشه بهتر است کار کنید. با چندین شی در یک زمان به جای اینکه با اشیا به گونه ای رفتار کنیم که در انفرادی کار می کنند.
هنگامی که جمعآوری زباله اتفاق میافتد، ممکن است اشیاء به مکانهای مختلف منتقل شوند تا فضایی در بخشها آزاد شود که اکنون گران است زیرا همه ارجاعات به اشیا باید به مکان -جدید- متفاوتی اشاره کنند.
برای کمک به GC چه کاری می توانید انجام دهید؟
اولین کار این است که حافظه اختصاص داده شده در وهله اول را به عنوان مثال کاهش دهیم:
- حذف فیلدهای استفاده نشده
- کوچک نگه داشتن اندازه اولیه ها تا حد امکان
- تخصیص حافظه از قبل
- مقداردهی اولیه اشیا در صورت نیاز
قاعده کلی این است که اشیاء باید طول عمر محدودی داشته باشند تا زبالهگیر اصلاً آنها را در نظر نگیرد. از سوی دیگر، اشیایی که در یک بازه بزرگتر استفاده می کنید باید یک بار ارجاع داده شوند و باید نگهداری و نگهداری شوند تا قابل استفاده مجدد باشند.
اشیاء کوچک باید درست قبل از استفاده از آنها تخصیص داده شوند و اشیاء بزرگ باید از قبل تخصیص داده شوند، بنابراین هزینه تخصیص آنها در مرحله اولیه است و نه در میانه پردازش برنامه شما.
اشیاء موقت باید در زمانی که دیگر مورد نیاز نیستند روی null تنظیم شوند و همین امر برای اعضای یک کلاس ایستا زمانی که مقادیر آن دیگر مورد نیاز نیست صدق می کند. وجود ارجاعات اشیاء تو در تو نیز به یک مشکل تبدیل می شود زیرا پیش بینی طول عمر اشیا دشوار است.
اشیاء یکبار مصرف
تخریبکنندهها توسط جمعآورنده زباله یکی پس از دیگری پس از جمعآوری فعال میشوند، تا زمانی که Dipose قبل از یادآوری فراخوانی شود، شی بدون نیاز به فراخوانی تخریبکننده حذف میشود. بنابراین الگوی Dispose باید به جای داشتن یک تخریبگر با تمام منطق پاکسازی در متد Dispose استفاده شود، این کد باید به همان اندازه ساده باشد که فقط حافظه ای را که متعلق به شی است لمس می کند بدون هیچ تضمینی مبنی بر اینکه ممکن است هنوز معتبر باشد.
مارشال کردن
مشکل کپی کردن بافرها این است که داده ها جابه جا می شوند، به عنوان مثال هنگام استفاده از LINQ برای تغییر فهرستی از آرایه ای از عناصر، این داده ها در فضای حافظه دات نت کپی می شوند و سپس به فضای حافظه برنامه شما باز می گردند که هزینه زیادی دارد.
به طور کلی، اشیا باید به سرعت ایجاد و از بین بروند. با ارجاعات ثابت، اشیاء در طول عمر برنامه زندگی می کنند و باید در استخرها مدیریت شوند.
مجموعههای بزرگی از عناصر باید ادغام شوند و در صورت لزوم به آنها ارجاع داده شود، یکی از راههای انجام این کار مدیریت استخر با الگوی یکبار مصرف است که در آن روش Dispose، شیء جمعشده را به استخر برمیگرداند تا مورد استفاده مجدد قرار گیرد، با در نظر گرفتن اینکه باید کنترل کامل بر آن داشته باشد.
هنگام از پیش تخصیص اشیاء بزرگ، آنچه باید دنبال شود، مجموعه ای اجباری از فراخوانی GC است GC.Collect
بنابراین جسم بزرگ می تواند جایگزین چیزی شود که قرار بود به عنوان زباله از بین برود و در عین حال انبوه را به دلیل تکه تکه شدن متراکم کند. هنگامی که این اشیاء در قسمتی قرار می گیرند که در آن برای طول عمر برنامه زندگی می کنند، می توان آنها را با خیال راحت جمع کرد و در صورت لزوم از آنجا ارجاع داد.
ذخیره سازی
هنگامی که می خواهید اشیایی را که برای ایجاد آنها گران هستند نگهداری کنید، References ضعیف برای ذخیره آنها مفید است، زمانی که حافظه در دسترس محدود است مانند دستگاه های تلفن همراه یا زمانی که اشیاء بزرگ به راحتی ایجاد می شوند و نیازی به داشتن آنها نیست، باید به این موضوع توجه کنید. در صورتی که از آنها استفاده نمی کنید