PDA

View Full Version : مشکل اساسی با حافظه سیستم



ferankyy
یک شنبه 20 فروردین 1391, 13:04 عصر
با سلام خدمت اساتید

من یه برنامه چاپ کارت نوشتم که با 18 پرینتر کار می کند . یعنی وقتی برنامه اجرا میشه اطلاعات از بانک اطلاعاتی دریافت و سپس این اطلاعات به عکس تبدیل شده و با استفاده از دستورات خود پرینتر به پرینتر ها ارسال میشه ( در ضمن برنامه برای چاپ کارت PVC هست و پرینتر های مخصوص داره ) این کار بر اساس تعداد رکورد های بانک اطلاعاتی تکرار میشه و بین پرینتر ها تقسیم میشود . مشکل اینجاست که وقتی تعداد چاپ ها به حدود 500 تا 600 عدد میرسه برنامه ارور System Out Of Memory میده و باید برنامه حتما بسته بشه و دوباره باز بشه تا شروع به کار کنه .
در ابتدا فکر کردم که به خاطر این هست که چون هر بار که رکورد از دیتابیس دریافت میشه ، اطلاعات اون به عکس تبدیل میشه و کنار برنامه ذخیره میشه و به پرینتر ارسال میشه و دوباره پاک میشه . و برای حل مشکل تمامی دستوراتی که برای خواندن و ذخیره عکس روی هارد بود را با استفاده از Using انجام دادم که بعد از پایان هر پرینت از بین بروند . ولی بازم این مشکل به وجود آمد و به این نتیجه رسیدم که هر اتفاقی میفته داخل SDK خود پرینتر هست که این عکس ها رو برای چاپ بهش میفرستم ( در ضمن این پرینتر ها برای اینکه بتونه با دستورات خودش رنگی چاپ کنه باید ابتدا آدرس عکس سیاه و سفید اطلاعات و سپس آدرس عکس خود فرد را به یه تابع که داخل DLL چاپ هست بفستیم و اون عملیات چاپ رو انجام میده ) و به همین دلیل اون قسمت از دستورات که آدرس عکس ها رو برای چاپ به SDK میداد رو حذف کردم ( یعنی در واقع دستوری برای چاپ به پرینتر ها ارسال نمیشد و فقط برنامه رکورد ها را از بانک دریافت ، عکس ها رو ساخته و روی هارد ذخیره میکرد و دوباره پاک میکرد ) برنامه رو اجرا کردم و دیگه اون ارور صادر نشد . و به این نتیجه رسیدم که وقتی آدرس عکس ها رو برای چاپ به SDK میدیم بعد از 500 تا 600 بار ارسال برنامه ارور System Out Of Memory میده . بعد با استفاده از ابزار Reflactor کد های SDK رو گرفتم و کلاسی که با عکس کار میکرد رو از IDispsable ارث بری کردم که بتونم SDK رو با استفاده از Using فراخونی کنم که در پایان چاپ از حافظه خارج بشه ولی بازم نشد . در ضمن داخل اون SDK آدرس عکس ها به یه تابع که مثل توابع API بود ارسال میشد و سپس عکس ها تبدیل به Byte و به پرینتر ارسال میشدند . همچنین داخل SDK از دستور Marshal.Copy() استفاده شده بود که یکی از پارمتر های ورودی این تابع ، عکسی بود که به بایت تبدیل شده بود .

(برای هر پرینتر یک BackgroundWorker ساخته میشه و شروع به کار میکنه)

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

hakim22
یک شنبه 20 فروردین 1391, 14:27 عصر
به نظر من ساده ترین کار اینه که یک برنامه ی دیگه بسازی که این برنامه رو اجرا بکنه ، و به تعداد محدودی که اجرا شد ببندش و دوباره از طریق اون برنامه اجراش کنی، کار مشکلی هم نیست و زیاد هم طول نمیکشه.

در هر صورت توضیحات نشون میده شما کنترلی روی سیستم پرینت و خالی کردن حافظه ی اون بخش رو ندارید.

ferankyy
یک شنبه 20 فروردین 1391, 23:35 عصر
به نظر من ساده ترین کار اینه که یک برنامه ی دیگه بسازی که این برنامه رو اجرا بکنه ، و به تعداد محدودی که اجرا شد ببندش و دوباره از طریق اون برنامه اجراش کنی، کار مشکلی هم نیست و زیاد هم طول نمیکشه.

در هر صورت توضیحات نشون میده شما کنترلی روی سیستم پرینت و خالی کردن حافظه ی اون بخش رو ندارید.

خوب این ساده ترین راه هست .
ولی حتما راه اصولی تر هم داره که بشه باهاش حافظه رو خالی کرد .
دوستان کمک کنید .

aghayex
یک شنبه 20 فروردین 1391, 23:55 عصر
شما بعد از اینکه هر عکر به پرینتر فرستادی و دیگه کارت با اون رکورد تموم شد تمام اون اشیاتو دیسپوس کن بعد این کد رو بدون دستکاری بنویس انشا ا... کارت راه می یوفسته
اگه مشکلت حل شد یه دعا باسه بکن که به مقصودمون برسیم

System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess();
try
{
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet);
}
catch{}

hakim22
دوشنبه 21 فروردین 1391, 09:35 صبح
نمیشه که شما حافظه ای که یک برنامه ی دیگه ایجاد کرده خالی کنید ، در این صورت هزار جور مشکل ممکنه پیش بیاد.
شما از یک dll برای چاپ استفاده می کنید. اگر در اون dll هیچ تابعی برای خالی کردن حافظه ایجاد نشده خالی کردن دستی مفهوم نداره .

ferankyy
دوشنبه 21 فروردین 1391, 14:08 عصر
به نظر شما اگر Virtual Memory مربوط به هارد دیسک رو افزایش بدم مشکل حل میشه ؟

PetekDincos
دوشنبه 21 فروردین 1391, 14:40 عصر
با سلام
تو این لینک یه راهکاری ارائه شده ببین کارت رو راه می اندازه با تشکر
Link (http://mbnsoft.ir/index.php/article/net-framework/11-article/net-framework/20-article2.html)

hakim22
دوشنبه 21 فروردین 1391, 14:45 عصر
خب چرا دست روی دست گذاشتید !؟ امتحان کنید !

aghayex
دوشنبه 21 فروردین 1391, 14:53 عصر
به نظر من ویِژوال دات نت در مدیریت حافظه خوب عمل نمییکنه چون خودم در یه برنامه گزارش ساز بهش برخوردم اینو می گم اگه گزارشم 5 برگ پشت سر هم بود برنامم خیلی سنگین میشد و کدهام هم مشکلی درش نبود اما همین که از این کد استفاده کردم کارم درست شد و هیچ مشکلی هم پیش نیومد .

ferankyy
سه شنبه 22 فروردین 1391, 20:30 عصر
با تشکر از همه دوستان .
من برنامه را اجرا کردم و از داخل TaskMgr کنترلش کردم و به این نتیجه رسیدم که Memory Commit Size برنامه داخل TaskMgr که به حدود 1,800,000 KB مبرسه برنامه ارور میده .

aghayex
جمعه 25 فروردین 1391, 11:48 صبح
من برنامه را اجرا کردم و از داخل TaskMgr کنترلش کردم و به این نتیجه رسیدم که Memory Commit Size برنامه داخل TaskMgr که به حدود 1,800,000 KB مبرسه برنامه ارور میده .

خوب اون کد رو که بهت دادم این فضا رو آزاد می کنه

ferankyy
جمعه 25 فروردین 1391, 19:08 عصر
خوب اون کد رو که بهت دادم این فضا رو آزاد می کنه
کدی که شما دادید رو تست کردم ولی جواب نداد :گریه: