PDA

View Full Version : سوال: تابع Finalize چه زماني اجرا ميشه ؟



ebrahimv
سه شنبه 12 بهمن 1389, 17:12 عصر
Protected Overrides Sub Finalize()

MyBase.Finalize()
End Sub

mehdi.mousavi
پنج شنبه 14 بهمن 1389, 01:24 صبح
سلام.
این متود هنگامی Call میشه که GC دیگه به Object شما نیاز نداشته باشه و بخواد اونو به کلی نابود کنه و از بین ببره. در حالت عادی، شما باید از override کردن این متود صرف نظر کنید، چون اولا معلوم نیست که تو Context چه Thread ای این متود Call بشه، ثانیا هیچ ترتیبی در فراخوانی این متود روی Object های مختلف وجود نداره، ثالثا ممکنه یه Object با متود GC.SupressFinalize محافظت شده باشه، در نتیجه، Finalizer اش Call نخواهد شد. بهتره تا شما IDisposable رو روی کلاستون پیاده سازی کنید، هر وقت هم کارتون با کلاس مربوطه تموم شد، متود Dispose رو فراخوانی کنید.

موفق باشید.

ebrahimv
پنج شنبه 14 بهمن 1389, 09:35 صبح
پس اين تابع موقع نابود سازي كاس اجرا ميشه
حالا من يه فرم رو به نمايش در اوردم بعد بستم و حتي ديسپوز كردم اين تابع اجرا نشد و حجم فرمم هم از رم كم نشد
مشكل اينجاست كه من يه فرم سنگين دارم و وقتي نمايش ميدم بعد ميبندم تو رم ميمونه و وقتي اين فرم رو مثلا 100 بار باز و بسته ميكنم رم پر ميشه و خطا ميده

پيشنهادتون چي هست؟

mehdi.mousavi
پنج شنبه 14 بهمن 1389, 11:09 صبح
پس اين تابع موقع نابود سازي كاس اجرا ميشه حالا من يه فرم رو به نمايش در اوردم بعد بستم و حتي ديسپوز كردم اين تابع اجرا نشد و حجم فرمم هم از رم كم نشد مشكل اينجاست كه من يه فرم سنگين دارم و وقتي نمايش ميدم بعد ميبندم تو رم ميمونه و وقتي اين فرم رو مثلا 100 بار باز و بسته ميكنم رم پر ميشه و خطا ميده پيشنهادتون چي هست؟

سلام.
ببینید، من نگفتم Dispose کردن یک کلاس باعث فراخوانی Finalizer اون کلاس میشه. خیر؛ ابدا. این GC هستش که در سطوح مختلف و بر اساس روند کاری خودش تصمیم میگیره کی حافظه گرفته شده رو Reclaim کنه. البته شما می تونید از GC بخواهید که کلیه Generation ها رو Collect کنه (که نتیجه اش، آزاد سازی حافظه گرفته شده هستش). برای این کار، میتونید از GC.Collect استفاده کنید فقط دقت کنید که با اینکار Finalizer ها در Thread های جداگانه Call میشن، بنابراین باید بعد از فراخوانی این متود حتما منتظر اتمام کار بمونید. این انتظار کشیدن توسط GC.WaitForPendingFinalizers میسره... در کل من این روشها رو پیشنهاد نمیکنم، چون ممکنه مشکلات دیگه ای رو در پی داشته باشه. برای اطلاعات بیشتر و مشاهده یک نمونه کد، لطفا به این آدرس (http://www.developer.com/net/csharp/article.php/3343191/C-Tip-Forcing-Garbage-Collection-in-NET.htm) رجوع کنید.

موفق باشید.

ebrahimv
پنج شنبه 14 بهمن 1389, 11:50 صبح
ممنون از شما چيزاي جابي ياد گرفتم
اما اين دستورات باعث نشد رم خالي بشه
ايا راه حل ساده اي نيست
اين عمل شما اگرم بشه زمان گيره
و اين كه اين عمل رو هر جا بنويسم رو كل پروژه اعمال ميشه؟

mehdi.mousavi
پنج شنبه 14 بهمن 1389, 12:08 عصر
اين دستورات باعث نشد رم خالي بشه ايا راه حل ساده اي نيست

سلام.
خیر متاسفانه. راه حل ساده ای وجود نداره. حتی ممکنه بدلیل وجود Circular Reference ها در برنامه حافظه مورد نظر شما هرگز آزاد نشه (این چیزی نیست که بشه اینجا، بدین شکل در موردش صحبت کرد و نیازمند بررسی جزء به جزء کد هستش).


اين عمل شما اگرم بشه زمان گيره و اين كه اين عمل رو هر جا بنويسم رو كل پروژه اعمال ميشه؟
بله، بسته به گسستگی Managed Heap این عملیات زمان بر هستش، اما هر جا بنویسید، روی Managed Heap تاثیر میذاره...

به اعتقاد من برای پیدا کردن Leak نام برده، شروع کنید به Comment کردن بخشهای مختلف کد (در فرم مورد نظر). یعنی تا حد امکان، Code های نوشته شده رو Comment کنید و میزان مصرف حافظه رو بررسی کنید. اینقدر باید این عمل رو تکرار کنید تا Code Block (ها)یی که دچار این مساله شده اند رو پیدا کنید. بطور نمونه باید GDI Object Handle ها رو Trace کنید و به اونها چشم بدوزید (چون ممکنه بخشی از این هدررفت حافظه بدلیل عدم آزاد سازی GDI Object ها باشه). خلاصه یکی از بهترین روشها، همین ساده سازی کد در مراحل مختلف و بررسی نتایج هستش.

موفق باشید.

ebrahimv
پنج شنبه 14 بهمن 1389, 12:54 عصر
ممنون از دوست عزيز كه خيلي خوب راهنمايي كرديد ولي اين دستورات باعث نشد كه رم ازاد بشه

به اعتقاد من برای پیدا کردن Leak نام برده، شروع کنید به Comment کردن بخشهای مختلف کد (در فرم مورد نظر). یعنی تا حد امکان، Code های نوشته شده رو Comment کنید و میزان مصرف حافظه رو بررسی کنید. اینقدر باید این عمل رو تکرار کنید تا Code Block (ها)یی که دچار این مساله شده اند رو پیدا کنید. بطور نمونه باید GDI Object Handle ها رو Trace کنید و به اونها چشم بدوزید (چون ممکنه بخشی از این هدررفت حافظه بدلیل عدم آزاد سازی GDI Object ها باشه). خلاصه یکی از بهترین روشها، همین ساده سازی کد در مراحل مختلف و بررسی نتایج هستش.

از اين قسمت چيزي نفهميدم ميشه بيشتر توضيح بديد اگه امكان داره يه مثال بزنيد

بزاريد سوالم رو بهتر بپرسم
فرض كنيد يه برنامه براي يه سازمان با ترافيك كاري بالا هست كه صبح باز ميشه و حد اقل تا ظهر باز هست و بسته نميشه
خوب با اين چيزايي كه من فهميدم و ميبينم ابجكتها فضاي خودشون رو بعد از ديسپوز شدن هم از دست نميدن كه باعث ميشه برنامه رفته رفته سنگين بشه و كند اين كندي تا جايي امكان داره رخ بده كه رم پر شه و برنامه خطا بده به خصوص اگه رم سيستم كم باشه

من در كل دنبال روشي براي حل اين مشكل هستم.

hero4000
شنبه 16 بهمن 1389, 08:51 صبح
دوست عزيز مي دونم چي مي کشي آخه من هم قبلا اين مشکل رو داشتم و خيلي اين در و اون در زدم تا جواب رو گير بيارم ولي هيچکس جواب درست و حسابي بهم نداد .

يک روز خودم اتفاقي جوابم رو بدست آوردم .

شما فرم اصلي برنامت رو ( همون فرمي که اون فرم حافظه پر کن رو صدا مي زنه ) رو مينيمايز کن و بعدش به حالت قبلي برگردون و نتيجه رو ببين ( خيلي جالبه ) :چشمک: