PDA

View Full Version : بیشتر شدن فضای اشغال شده در رم توسط برنامه به مرور زمان



alaveh
جمعه 27 آبان 1390, 16:08 عصر
سلام

دوستان برنامه ای که نوشتم رو وقتی اجرا می کنم و مصرف رم رو نگاه می کنم می بینم هر بار که یک فرم رو باز می کنم مقداری از رم رو اشغال می کنه و با بسته شدن اون فرم با وجود اینکه فرم رو Free می کنم باز هم اون فضا به رم بر نمی گرده . گویا متغیرها فضا رو رها نمی کنند . آیا راهی هست که کل فضا رو برگردونم ؟

یک سوال دیگه : فرمم رو Showmodal می کنم معمولا ولی بعضی وقتا فرم showmodal شده می پره میره پشت فرم قبلی و دیگه نمیشه کاری کرد . باید برنامه رو از توی task manager بست . کسی راهی به ذهنش می رسه که جلوی این کار رو گرفت ؟

سعید صابری
جمعه 27 آبان 1390, 17:50 عصر
این شاید بدردت بخوره. (http://barnamenevis.org/showthread.php?283172-%D9%85%D8%B4%DA%A9%D9%84-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%AF%D8%B3%D8%AA%D9%88%D8%B1%D8%A7%D8%AA-free-%D9%88-destory&highlight=freeandnil)

SAASTN
جمعه 27 آبان 1390, 21:10 عصر
بررسی کنید که این حافظه درست با نمایش فرم تخصیص پیدا می کنه یا مستقل از اونه. و این که در هنگام نمایش فرم کم و زیاد میشه یا نه.
احتمالا در زمان اجرا اشیائی رو میسازید و موقع آزاد کردن فرم، اونها رو آزاد نمی کنید. اگر اینطور هست و اگر این اشیائ ظاهری هستند(یا کلا از TComponent مشتق شدن) موقع ساختن Owner اونها رو خود فرم تعیین کنید تا موقع آزاد سازی فرم، این اشیا هم به همراهش آزاد بشن.
اگر هم این اشیا Owner ندارند، موقع ایجادشون توی یک فیلد از فرم اصلی نگهداریشون کنید و توی OnDestroy فرم آزادشون کنید.

البته من یادمه توی دلفی 6 و 7 وقتی توی با یه Timer بصورت متوال روی یه Canvas ترسیم میکردم به مرور زمان حافظه تخصیصی مربوط به Process برنامم افزایش پیدا می کرد. البته اخیرا این مورد رو تو ورژن های جدید تر دلفی چک نکردم.

alaveh
شنبه 28 آبان 1390, 16:29 عصر
والا من نمی دونم owner کیه . یک فرمه که روش هم یک سری کامپوننته مثل چک باکس و ادیت و باتن و ....

من فکر می کنم که اون رمی که آزاد نمیشه مال متغیرها باشه نه کامپوننتها

حافظه هم همونطور که اشاره کردم با Create فرم اشغال میشه و با Free بخشی از اون آزاد میشه .

SAASTN
شنبه 28 آبان 1390, 19:54 عصر
احتمالا در زمان اجرا اشیائی رو میسازید و موقع آزاد کردن فرم، اونها رو آزاد نمی کنید.
این جمله رو خوندید؟ بالاخره در زمان اجرا شیئی میسازید یا نه؟ یا با کد کلاسی Create می کنید؟

alaveh
دوشنبه 30 آبان 1390, 20:01 عصر
نه

فقط متغیر

تنها create برای ساخت فرم هست که اونم free میشه زمان بستنش

SAASTN
دوشنبه 30 آبان 1390, 21:34 عصر
سخت شد که!
برو تو سورس پروژه بعد از begin اینو بذار:
ReportMemoryLeaksOnShutdown := True;
بعد برنامه رو تو حالت Debug اجرا کن و برو فرم باز کن و ببند و بعد برنامه رو ببند، موقع بستن برنامه جاهایی که نشت حافظه داشتی رو گزارش می کنه، نوع داده شم می نویسه.
البته این تو دلفی 7 کار نمی کنه، من با XE چک می کنم. اینم یه نگاه بکن:
http://barnamenevis.org/showthread.php?254839-%D8%A2%D8%B2%D8%A7%D8%AF-%D8%B4%D8%AF%D9%86-%D8%AD%D8%A7%D9%81%D8%B8%D9%87/page2
با چه ورژنی کار می کنی؟ تو فرمه چه کامپوننتایی استفاده شده؟ فرم به دیتابیس وصل می شه؟

vcldeveloper
دوشنبه 30 آبان 1390, 22:13 عصر
با چه چیزی میزان مصرف برنامه را بررسی کردید؟ اگر با Task Manager بوده، که اون ابزار مناسبی برای این کار نیست، برای همچین کارهایی باید از Profiler های مناسب استفاده کنید. اگر فقط میخواید بدونید که آیا Memory Leak دارید یا نه، همون کد پست شماره 7 کفایت میکنه، و اگر Memory Leak داشته باشید، FastMM در پایان اجرای برنامه بهتون میگه.
اون اطلاعاتی که در Task Manager می بینید دقیق نیست چون؛ وقتی شما یک شی را آزاد میکنید، ویندوز عجله ایی در پس گرفتن حافظه آزاد شده از برنامه شما نداره، بلکه تا زمانی که مجبور نشه، این حافظه را از برنامه شما پس نمیگیره. اگر با کمبود حافظه مواجه بشه، این حافظه رو از برنامه شما پس میگیره، و گرنه این حافظه را به صورت رزرو در اختیار برنامه شما میذاره تا شاید بعدا بهش نیاز پیدا کنید. پس لزومی نداره که با آزاد شدن هر فرم، Task Manager هم کاهش حافظه مصرفی را نمایش بده.

alaveh
چهارشنبه 02 آذر 1390, 23:46 عصر
با چه چیزی میزان مصرف برنامه را بررسی کردید؟ اگر با Task Manager بوده، که اون ابزار مناسبی برای این کار نیست، برای همچین کارهایی باید از Profiler های مناسب استفاده کنید. اگر فقط میخواید بدونید که آیا Memory Leak دارید یا نه، همون کد پست شماره 7 کفایت میکنه، و اگر Memory Leak داشته باشید، FastMM در پایان اجرای برنامه بهتون میگه.
اون اطلاعاتی که در Task Manager می بینید دقیق نیست چون؛ وقتی شما یک شی را آزاد میکنید، ویندوز عجله ایی در پس گرفتن حافظه آزاد شده از برنامه شما نداره، بلکه تا زمانی که مجبور نشه، این حافظه را از برنامه شما پس نمیگیره. اگر با کمبود حافظه مواجه بشه، این حافظه رو از برنامه شما پس میگیره، و گرنه این حافظه را به صورت رزرو در اختیار برنامه شما میذاره تا شاید بعدا بهش نیاز پیدا کنید. پس لزومی نداره که با آزاد شدن هر فرم، Task Manager هم کاهش حافظه مصرفی را نمایش بده.

ممنون

توضیح خوبی بود

نمی دونستم

بله با تسک منیجر چک می کنم و می دیدم که مقداری از حافظه پس داده نمیشه . باز هم ممنون

alaveh
چهارشنبه 02 آذر 1390, 23:58 عصر
سخت شد که!
برو تو سورس پروژه بعد از begin اینو بذار:
ReportMemoryLeaksOnShutdown := True;
بعد برنامه رو تو حالت Debug اجرا کن و برو فرم باز کن و ببند و بعد برنامه رو ببند، موقع بستن برنامه جاهایی که نشت حافظه داشتی رو گزارش می کنه، نوع داده شم می نویسه.
البته این تو دلفی 7 کار نمی کنه، من با XE چک می کنم. اینم یه نگاه بکن:
http://barnamenevis.org/showthread.php?254839-%D8%A2%D8%B2%D8%A7%D8%AF-%D8%B4%D8%AF%D9%86-%D8%AD%D8%A7%D9%81%D8%B8%D9%87/page2
با چه ورژنی کار می کنی؟ تو فرمه چه کامپوننتایی استفاده شده؟ فرم به دیتابیس وصل می شه؟

ممنون
منم از XE استفاده می کنم . به SQL Server 2008 وصل میشه . کامپوننتهای دلفی ( بیت باتن و ادیت و کومبو و گرید و مدیا پلیر و لیبل و لیبل ادیت و کامپوننتهای ADO و از همین چیزا )

اون کد رو اضافه کردم و چند تا فرم رو باز کردم و مقداری حافظه هم اشغال شد و موقع بستن هم آزاد نشد ولی گزارشی ندیدم . کجا اون گزارش رو می تونم ببینم ؟

هر چند آقای کشاورز به مطلب جالبی اشاره کردند ولی می خوام در مورد این گزارش بدونم . کمک می کنه بهم .

Felony
پنج شنبه 03 آذر 1390, 05:54 صبح
هر چند آقای کشاورز به مطلب جالبی اشاره کردند ولی می خوام در مورد این گزارش بدونم . کمک می کنه بهم .
وقتی ReportMemoryLeaksOnShutdown رو True میکنی ؛ بعد از بسته شدن برنامه اگر Memory Leak ی در جایی از برنامه شناسایی بشه به صورت خودکار بعد از بسته شدن برنامه تو یک Message Box نمایش داده میشه ، مثلا کد زیر رو اجرا کنید و برنامه رو ببندید :

var
B: TButton;
begin
B:= TButton.Create(nil);
end;

alaveh
پنج شنبه 03 آذر 1390, 11:40 صبح
وقتی ReportMemoryLeaksOnShutdown رو True میکنی ؛ بعد از بسته شدن برنامه اگر Memory Leak ی در جایی از برنامه شناسایی بشه به صورت خودکار بعد از بسته شدن برنامه تو یک Message Box نمایش داده میشه ، مثلا کد زیر رو اجرا کنید و برنامه رو ببندید :

var
B: TButton;
begin
B:= TButton.Create(nil);
end;
ممنون آقای تاجیک

جواب داد . هر چند حدود 10 خط پیام داد که اینا حافظه اشغال کردن و پس ندادن و نمیشد متوجه شد که داره چی میگه ولی بالاخره مشخص می کنه که وقتی فلان فرم باز میشه داره حافظه از دست میره و این خیلی عالیه .

همه دوستان لطف کردند .