View Full Version : Memory Leak
A.Nemati
شنبه 15 تیر 1387, 18:09 عصر
كسي ميتونه تمام حالتهايي كه Memory Leak در برنامه اتفاق ميافته شرح بده؟!
ممنون.
Hsimple11
شنبه 15 تیر 1387, 20:14 عصر
نشت حافظه (Memory Leakage)
نشت حافظه یا نشت ریسورس (Resource Leakage) زمانی رخ می دهد که یک برنامه نتواند حافظه ای را که از سیستم مصرف میکند آزاد کند. چنانچه این نشت متوالیا انجام شود باعث اشغال حجم نامحدودی از ظرفیت حافظه می گردد. اگر به نحوی از Leakage حافظه جلوگیری نشود این امر می تواند به قفل شدن سیستم نیز منجر شود.
یکی از این مثالها در دلفی زمانی است که میخواهیم یک شیئ را بسازیم (Create). می دانیم که پس از ساخت شی مورد نظر باید زمانی که دیگر به آن احتیاج نداریم حافظه ای که به آن تخصیص داده شده را آزاد کنیم. با بلوک Try...Finally جلوی این نشت حافظه را خواهیم گرفت.
زمانی که در حال طراحی یک برنامه (Design Time) هستیم و کامپوننت های مختلف را به عنوان مثال بر روی فرم خود قرار میدهیم نگرانی در مورد حافظه و نشت آن نداریم چرا که هر شیئ که در روی فرم قرار میدهیم، فرم مالک (Owner) آن شیئ شده و زمانیکه فرم تخریب شود، حافظه اختصاص داده شده به اجزاء روی آن نیز آزاد میشود.در واقع اجزایی که بر روی فرم قرار میدهیم بطور اتوماتیک توسط Owner خود ساخته و تخریب می شوند.
همانطور که گفته شد بارزترین علت نشت حافظه ساخت اجزاء مختلف در زمان اجزا (RunTime) است. فرض کنید در برنامه خود یک کلاس تعریف کرده اید و میخواهید شیئی از این کلاس را بسازید.(زمانی که مالک شئیتان Self و یا nil و آزادسازی حافظه با خودتان است) این متد (Create) مقداری از حافظه را به شئی جدیدی که مبخواهید بسازید احتصاص داده و اگر این حافظه را آزاد نکنید (با متد Free) Memory Leakage رخ خواهد داد. برای اینکه از آزادسازی حافظه مطمئن باشید آن را در بلوک Try...Finally قرار می دهیم. مثال :
var
myForm : TMyForm;
begin
myForm := TMyForm.Create(nil) ;
try
{ دستورات دلخواه برنامه}
finally
myForm.Free;
end;
end;
یکی دیگر از جاهایی که نشت حافظه رخ میدهد زمانی است که از منابع خارجی (External Resources) در برنامه خود کمک میگیریم. مثلا با یک فایل خارج از برنامه با یک فایل متن، تصویر،... کار میکنیم و آن را در حافظه بارگذاری میکنیم. در این جا هم بایستی با متد CloseFile ، حافظه اختصاص داده شده را آزاد کنیم.
هنگام فراخوانی کتابخانه ها (فایلهای DLL) نیز باید بعد از اتمام کار آنها را از حافظه خارج کنیم. در واقع اگر از یک DLL خارجی در برنامه خود استفاده میکنیم متد FreeLibrary را نباید فراموش کنیم.
موفق باشید.....
A.Nemati
یک شنبه 16 تیر 1387, 09:59 صبح
ممنون.
دليل اين سوال اين بود كه وقتي با Eurekalog موارد Memory Leak را بررسي ميگردم، به مورد جالبي برخوردم:
TMyClass = class
private
FStr: String;
...
...
Constructor TMyClass.Create(Const Str1: string;Const Str2: string; Const pStr: String);
beign
...
FStr := pStr; // <-- Memory Leak here
...
end;
و فكر كردم كه حتما راجع به رشتهها حالت خاصي براي ايجاد Memory Leak وجود دارد.
منتظر نظرات دوستان هستم.
Hsimple11
یک شنبه 16 تیر 1387, 14:25 عصر
تفاوتی ندارد. در این جا هم نشت حافظه به علت ساخت یک لیست از رشته ها و آزاد نکردن حافظه اتفاق افتاده است. شما یک instance از کلاسی را که تحت عنوان TMyClass تعریف کرده اید با Constructor می سازید اما :
توجه داشته باشید که کلاسها اغلب اشیاو را در متدها و سازنده ها (Constructors) می سازند. جاهایی که از متد و پروسیجری برای ساخت شیئ یا اشیایی استفاده میشود مانند مثالی که در پست شماره 2 زده شد، باید آزاد شوند. اما اشیائی که در Constructor ایجاد میشوند باید توسط متد Destructor آزاد شود. در واقع شبیه مورد قبل با یک روند معکوس برای جلوگیری از Memory Leakage نیاز داریم مثال :
type
TMyClass = class
private
fileData : TStringList;
Public
Constructor Create(const fileName : string);
Destructor Destroy; override;
/// پروسیجرهای مربوطه
end;
موفق باشید...
vcldeveloper
یک شنبه 16 تیر 1387, 16:40 عصر
فكر كردم كه حتما راجع به رشتهها حالت خاصي براي ايجاد Memory Leak وجود دارد.
نوع داده string در دلفی reference-countred هست و بطور خودکار مدیریت میشه و لزومی نداره شما کار خاصی برای آزاد سازی داده های string در دلفی بکنید. شاید Memory Leak در خط قبلی یا بعدی خطی که گذاشتید اتفاق افتاده باشه.
این کلاس شما چکار انجام میده و نقش FStr و PStr در آن چی هست؟
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.