Speed Racer (15-09-21), vardipoor.m (15-09-21)
یعنی بخاطر رسم یه مستطیل ، از یه کتابخونه ای که به وب کم ربط داره ، استفاده کردید؟!!برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
نمیدونم منظورتون همینه و یا من بد متوجه شدم.
اگه همینه ، از شیِ Graphic میتونید همین کار را کنید . نیازی به استفاده از کتابخونه ی وبکم نیست!!
اگه گرافیک یا برنامه نویسی را کار نکردید و میخواید یه پروژه ی گرافیکی درست کنید ، قطعا یا شدنی نیست یا با مشکلات بسیار زیاد مواجه میشید . اگه این طوره ، حتما اول برید یاد بگیرید .
منظورم ، توصیف پروژه نبود . کد پروژه بود که خودتون باید تمام زوایاش را بررسی کنید .
مثال ، که در کد خودتون هم هست .برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
وقتی نوشتید :
using (var nextFrame = capture.QueryFrame())
، وقتی که کدِ بلاکِ using ، بسته شه ، هر منبعِ unmanaged ای که برای شیِ nextFrame در نظر گرفته شده بود ، از حافظه ، پاک میشه .
فرقی نداره که بجای استفاده از using در کد بالا ، شما متدِ dispose ئه شیِ nextFrame را فراخونی کنید . یعنی فرقی نداره که بجای کد بالا ، از nextFrame.Dispose() استفاده کنید (البته یه فرق خیلی کوچولو داره) .
اما فراخونیِ متدِ Dispose (یا استفاده از using) ، بسته به کار خودتون داره که چه زمانی کارتون با اون شی ، به اتمام رسید . اگه قبل از اتمام ، Dispose کنید ، امکان زیادی داره که زمان استفاده از شیِ مورد نظر ، با مشکل (و ارور زمان اجرا یا درست عمل نکردنِ شی و هر مشکل دیگه ای) مواجه بشید .
اون شیِ capture ، شی ای Dispose شدنی هست که زمانی که کارتون باهاش تمام شد ، باید Dispose اش کنید (که خودتون میدونید ، چه زمانی کارتون باهاش تمام میشه) .
اینکه رم تون هنوز پر میشه ، قبلا اشاره کردم .
Image ها هم Dispose شدنی هستند .
در pictureBox1.Image ، یه Image ئه جدیدی را در هر بار اجرای تایمر ایجاد میکنید که در اجرای بعدی ، Image های قبلی ای را که ایجاد کرده بودید ،در حافظه میذارید باقی بمونه و Dispose شون نمیکنید .
ضمن اینکه برای پاک کردنِ سریعترِ حافظه های managed هم (که قبلا گفته بودم) ، از متد GC.Collect() استفاده نکردید .
آخرین ویرایش توسط SajjadKhati در تاریخ 14-09-21 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (15-09-21), vardipoor.m (15-09-21)
خیر، درسته این کتابخونه برای پردازش تصویر هست اما من فقط تصویر وب کم خودم رو توی یه پیکچر باکس نمایش میدم همینیعنی بخاطر رسم یه مستطیل ، از یه کتابخونه ای که به وب کم ربط داره ، استفاده کردید؟!!
تصویر من، تصویر یه بازی آنلاین هست که یه کادر مستتطیل شکل هست. فرض کنید دارید از مانیتور کامپیوتر فیلم میگیرید همین
الان یه چیزی متوجه شدم اینکه حافظه اشغال میشه اما به یه حدی که رسید دوباره خالی میشه
Screenshot 2021-09-14 132249.jpg
حالت عادی روی 64 هست و موقع اجرای برنامه تا 79 میرشه و دوباره برمیگرده 64، این عادی هست؟
و اون موقع ارور داده بود چون رم من حدود 85 درصد پر بود و برنامه رو که اجرا کردم پر شد.
من از dispose استفاده کردم اما هیچ تاثیری نداشت
این دو خط رو به تایمر اضافه کردم
کد:myBitmap3.Dispose(); pictureBox1.Dispose();
آخرین ویرایش توسط vardipoor.m در تاریخ 14-09-21 انجام شده است
منظورتون اینه که بصورت پیش فرض ، برنامه تون از 64 مگابایت از رم استفاده میکنه؟برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
این ربطی به اصولی بودن کدتون نداره .
برنامه تون ممکنه 40 مگ (یا کمتر) از رم را اشغال کنه اما کدی نوشته باشین که یه متغییر و شی ای را تعریف کرده باشه اما زمانی که ازش استفاده نمیکنین و یا حتی بعد از بستنِ برنامه تون ، حافظه ای که براش گرفته شده را به سیستم عامل ، پس نده و کماکان اشغال کنه .
که جریانش (جریان آزادسازی حافظه های unmanaged) را توضیح دادم .
نگفتم که استفاده از Dispose ، اون میزان از آزادسازی ای از رم که مد نظرتون هست ، تاثیر داره یا تاثیر نداره .برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
Dispose ، باعث میشه منابع حافظه که برای حافظه های نوع unmanaged (نه همه ی نوع حافظه که شامل managed هم میشه) برای اون شی استفاده میشه ، از حافظه ، آزاد بشه .
مقدار این حافظه ی unmanaged برای اون شی ، میتونه در حد چند بایت باشه ، یا در حد کیلو یا شاید مگا یا گیگابایت . مقدار حافظه ی unmanaged برای اون شی را فقط کسی که کتابخونه اش را ساخت ، میدونه .
وظیفه ی شما به عنوان برنامه نویس فقط اینه که اگه شیِ جدیدِ Dispose شدنی ای را به متغییری اختصاص دادین ، بعد از اتمام کارتون با اون متغییر ، این متد را فراخونی کنین تا منابع حافظه ی unmanaged اش از حافظه ، پاک شه . اما اینکه چه حجمی از حافظه ی unmanaged ، به این شی اختصاص داده شده بود ، فقط به کسی که کتابخونه اش را نوشت ، مربوطه .
درباره ی آزادسازیِ سریعترِ منابع managed (ای که اشاره گری بهش اشاره نمیکنه) هم که گفتم .
با این حال ، اینها ، این مقادیر را از حافظه پاک میکنن . نه صرفا از حافظه ی فیزیکی (رم) . بلکه برنامه ها از حافظه ی مجازی استفاده میکنن (شامل هم رم و هم pagefile ئه حافظه ی جانبی) .
اگه فرضا تغییرات حافظه را از قسمت نمودار memory در task manager پیگیری میکنید ، اون نمودار فقط تغییرات حافظه ی فیزیکی (رم) را نشون میده .
-----------------
دقت کنید که pictureBox1 را (مثل همه ی اشیاء دیگه) ، زمانی Dispose کنید که :
- اولا ، خودتون یه شیِ جدیدی از pictureBox ساخته باشید . یعنی زمانی که خودتون (new PictureBox را نوشته باشید) .
یعنی زمانی که pictureBox را زمانی که فرم را طراحی میکردید (زمانِ design در form) ، اضافه کردید ، برای این نوع pictureBox ، نیازی به Dispose کردن ، نیست .
- و دوما به کنترلِ pictureBox1 ، نیازی ندارید . یعنی فرضا میخواید pictureBox1 را از روی form تون حذف کنید . یا اینکه میخواید از برنامه بیرون برید .
بنابراین اگه احتمالا زمان طراحی فرم ، pictureBox1 را اضافه کردید (که احتمالا همینطوره) ، نیازی به اجرای کدِ pictureBox1.Dispose() نیست .
و همچنین ، زمانی شیِ myBitmap3 را هم Dispose کنید که دیگه در جای دیگه ای ازش استفاده نمیکنید و لازم تون نمیشه .
یعنی مثلا زمانی شیِ myBitmap3 را هم Dispose کنید که در pictureBox1.Image (یا هر جای دیگه) ، دیگه از شیِ myBitmap3 استفاده نمیکنید .
آخرین ویرایش توسط SajjadKhati در تاریخ 14-09-21 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (15-09-21), vardipoor.m (15-09-21)
اون تصویر که مقدار رم رو نشون میده تصویر برنامه hwinfo است که مقدار اشغال شده رو به درصد نشون میده یعنی 64 درصد که چون رم من 8 گیگ هست میشه حدود 5 گیگ
آقا من چون مثل شما زیاد تخصصی نیستم اودم با آزمون خطا پیدا کردم
یه کد رفرش فرم زدم
دیم که اصلا از 60 بالا نمیره!کد:this.refresh()
به نظزتون چطور میتونم هندلش کنم
آخرین ویرایش توسط vardipoor.m در تاریخ 14-09-21 انجام شده است
برنامه ی hwinfo چرا؟!!برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
شما باید برنامه ی خودتون را دقیق رصد کنید که چه نوعی ، فعلا داره چه مقدار حافظه را مصرف میکنه .
در ویژال استودیو ، از قسمت Memory Usage در Diagnostic Tools ، باید snapshot بگیرید تا متوجه بشید .
snapshot را هم حداقل 2 بار باید بگیرید . یک بار break point را قبل از اینکه کد مورد نظرتون (که از رم زیادی استفاده میکنه) ، بذارید و snapshot بگیرید و بار دوم ، f10 را بزنید تا اجرای کد ، به کدهای مورد نظرتون (که رم بالایی را استفاده میکنن) ،برسه و دومین snapshot را بگیرید و مقدار حافظه ی تمام اشیاءِ اون نوع را مقایسه کنید :
Measure memory usage in your apps - Visual Studio (Windows) | Microsoft Docs
و
Analyze memory usage in the Performance Profiler - Visual Studio (Windows) | Microsoft Docs
دقت کنید که در snapshot ، صرفا اطلاعات مقدار حافظه ای که برای تمامِ اشیاهایی از برنامه تون ، از یک نوعِ خاصی هست (مثلا تمام اشیایی که از نوع Bitmap هست) را بهتون میده .
برای جستجوی نوع داده (گرفتنِ مقدار حافظه ی اشغالی برای تمام اشیایی که از اون نوع هست) هم وقتی روی لینکِ snapshot ای کلیک کردید و به تصویرِ زیر رسیدید (که در لینک اول در بالا که گذاشتم ، توضیح میده) ، یه کادرِ جستجو ، در قسمت بالا ، سمت راست صفحه داره که میتونید نامِ نوعِ تمام اشیایی از اون نوع که در کل برنامه تون وجود داره را جستجو کنید که چقدر از حافظه مصرف میکنن (فرضا نوعِ Bitmap یا نوعِ Image را در این کادر میتونید بنویسید) (کادر در تصویر زیر مشخص هست) :
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
ربطی به حافظه ی اشغالی برنامه تون نداره .برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
اگه this ، شیِ فرم تون هست ، فرم تون را فقط ریفرش میکنه (نه کار دیگه ای) .
ممکنه در این لحظه ، گربگ کالکتور هم بخواد داده های managed را هم collect کنه (که قبلا بهتون گفتم که چجوری با کد این کار را کنید) .
به هر حال ، این کد ربطی به حافظه نداره .
-------------
لطفا اول کد نویسی سی شارپ را طبق منبعی که دادم (فیلم آموزش سی شارپ یا منابع انگلیسی) و همچنین کتابخونه های مورد نظرتون را (مثل گرافیک ، یا اون کتابخونه ای که برای وبکم بود و ...) که باز هم منابع یادگیری گرافیک (فیلم آموزش) را دادم ، اول کامل یاد بگیرید . بعد از یادگیری ، مشکلاتی که براتون بوجود میاد را بپرسید .
این طور که نمیشه بدون یادگیری دقیق بخواید برید سروقت پروژه . بسیاری سئوالات (از مبتدی گرفته تا بالاتر) براتون پیش میاد که با یادگیری زبان سی شارپ و کتابخونه ها ، این سئوالات از همون ابتدا براتون توجیه و قابل حل میشه .
پست قبلی (پست 13) ام را هم ویرایش کردم (بعد از خط چین) ، بخونید .
تاپیکی که اسمش را "شارپ کردن تصویر در c#" گذاشتید ، این انجمن ، با کاراکترهایی مثل # و اینها ، مشکل داره . واسه ی همین تاپیک تون نمایش داده نمیشه . بجای c# ، صرفا سی شارپ بنویسید (کلا کاراکتر # نداشته باشه) .
آخرین ویرایش توسط SajjadKhati در تاریخ 14-09-21 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (15-09-21), vardipoor.m (15-09-21)
برنامه hwinfo از قبل نصب بود و کلا همیشه دارمش
همونطور که بهتون گفتم حتی کد نمایش وب کم تو پیکچر باکس که همون چند خط اول هست رو به تنهایی هم بزنم حافظه زیاد میبره. حافظه رو با روش شما چک کردم و هر بار 867 مگ حافظه میگیره و دوباره ازاد میشه! اگه چند خط کد بیت مپ رو اضافه کنم که ترنسپرنت کنم و چاپ کنم رو فرم هر بار 1.9 گیگ حافظه میگیره دوباره آزاد میکنه! که فکر میکنم زیاد هست چون من حساب کردم چون دوربینم 60 فریم داره و تایمر هم 17 میلی ست شده یعنی هر ثانیه حدود 60 فریم ثبت میشه توی پیکچر باکس و چون 25 ثانیه طول برد تا حافظه آزاد شد پس 25*60= 1500 فریم توی پیکچر باکس ثبت شده که شده 867 مگ.
Screenshot 2021-09-15 005848.jpg
این عکس انالایز حافظه برای این کد هست
و میدونم الان میگید باید اسنپ شات میگرفتید اما گرفتم هیچ اشاره ای به هیچ چیز نکرده که شما گفتید مثلا بیت مپ یا پیکچر باکس من هرچه گشتم ندیدم، موجوده اگه گفتید اپلود میکنمکد:private void timer1_Tick(object sender, EventArgs e) { using (var nextFrame = capture.QueryFrame()) { if (nextFrame != null) { pictureBox1.Image = nextFrame.ToBitmap(); } } }
مگه شما نمیگید با استفاده از using بعد از اینکه کارش تمام شد حافظه رو آزاد میکنه الان فقط using تو کد هست ولی انگار فریم ها رو رو هم توی پیکچر باکس ذخیره میکنه و فریم قبلی رو پاک نمیکنه
من منظورم این نیست که این کد (()this.refresh)مدیریت حافظه میکنه اما دفدش کردن باعث میشه حافظه خالی بشه با همین کد بالا تست کردم به این صورت
نتیجه شد اینکد:private void timer1_Tick(object sender, EventArgs e) { using (var nextFrame = capture.QueryFrame()) { if (nextFrame != null) { pictureBox1.Image = nextFrame.ToBitmap(); this.Refresh(); } } }
Screenshot 2021-09-15 011339.jpg
فقط 200 مگ حافظه نهایت
gc collector هم دارم سرچ میکنم
فقط الان راهی هست سریع بشه توی تایمر بعد از هر بار که پیکچرباکس یه عکس توش قرار گرفت خالی بشه؟
یه همچین چیزی
picturebox1.image=null;
آخرین ویرایش توسط vardipoor.m در تاریخ 15-09-21 انجام شده است
آقا gc.collect() نوشتم عجب چیزیه
نمیزاره از 46 مگ میشتر بشه! برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
فقط یه سوال البته میدونم زیاد سوال پرسیدم ببخشد شما رو هم اذیت کردم این gc.collect() چطور فریم هایی که توی فرم چاپ شدن رو پاک نمیکنه یعنی برنامه من هیچ ایرادی توش نیفتاد ولی حافظه خالی شد! ظاهرا اشغال حافظه مال همین عکس های چاپ شده توی فرم و توی پیکچرباکس هستن یا من اشتباه میکنم؟کد:Capture capture = new Capture(); private void timer1_Tick(object sender, EventArgs e) { using (var nextFrame = capture.QueryFrame()) { if (nextFrame != null) { pictureBox1.Image = nextFrame.ToBitmap(); } } Bitmap myBitmap3 = new Bitmap(pictureBox1.Image); Color pixle1 = myBitmap3.GetPixel(100, 100); Color pixle2 = myBitmap3.GetPixel(400, 250); if (pixle1 == Color.FromArgb(24, 53, 73) || pixle2 == Color.FromArgb(24, 53,73)) { myBitmap3.MakeTransparent(Color.FromArgb(24, 53, 73)); gfx.DrawImage(myBitmap3, 1, 1); GC.Collect(); } else { GC.Collect(); } }
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
سلام
من هم قبلا بارها گفتم .
کدِ زیرتون :
یه شیِ بیت مپ جدید ایجاد میکنه (که این شی را به pictureBox1.Image اختصاص دادید) .کد:nextFrame.ToBitmap()
هر بار هم در تایمر ، ازش استفاده میکنید .
اما در تایمرِ بعدی که از این شی استفاده کردید ، این شیِ بیت مپِ قبلی را گفتید فورا از حافظه پاک کنه؟
نه .
بنابراین این شی های بیت مپ ، تجمع میشه و رم تون پر میشه .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
روش من چیه؟!!
من از خودم روشی ایجاد نکردم .
روال برنامه نویسی .net هست .
ببینید ، از هر شی ای بسازید و استفاده کنید (چه شیِ بیت مپ مثل کد بالا و هر شی ای) ، 2 حالت داره :
- حافظه ی managed ، برای اون شی اختصاص داده میشه .
- ممکنه هم علاوه بر این ، از حافظه ی Unmanaged هم استفاده بشه (این نوع اشیاء ، متد Dispose دارن) .
حالا برای پاک سازیِ هر نوع از این حافظه ها برای اون شی ، روشی متفاوت وجود داره :
- پاکسازی حافظه ی Unmanaged ، اغلب ، با متد Dispose انجام میشه .
- پاکسازیِ حافظه ی managed ، اول باید هیچ اشاره گری به اون شی ، اشاره نکنه و بعد اینکه با متد GC.Collect ، میتونین روند حذف حافظه های managed (ای که اشاره گری بهش وجود نداره) را درخواست بدین که در اولین فرصت این کار انجام بشه .
اگه از متد GC.Collect استفاده نکنین ، گربگ کالکتور ، این روند که پاکسازی حافظه های managed (ای که اشاره گری بهش وجود نداره) را میذاره برای وقتی که خودش به صلاح بدونه (مثلا موقعی که برنامه تون را میبندید یا زمانی که حافظه ی سیستم ، پر شده باشه و ...) . یعنی اگه از اون متد استفاده نکنین ، گربگ کالتور ، عجله ای در بررسی و آزادسازیِ حافظه های managed (ای که اشاره گری بهش وجود نداره) ، نمیکنه .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
فاصله ی زمانی تایمر (که 17 میلی ثانیه گذاشتین) ، اولا که فکر نکنید دقیقا هر 17 میلی ثانیه اجرا میشه .
بلکه این فاصله ی زمانی ، حتی اگه پردازنده مشغول نباشه ، دقیق نیست . یعنی اجراش ،اندکی ممکنه جلو و عقب بشه .
اگه عواملی مثل اِشغالِ پردازنده هم وجود داشته باشه که احتمال داره تاخیرش بیشتر بشه .
اما در کل تاخیرش خیلی زیاد نیست .
ولی اگه برای زمان های طولانی بخواین روی فاصله ی زمانیِ تایمر ، حساب باز کنید ، این تاخیر خودش را کاملا واضح نشون میده . مثلا برای یکسان کردنِ رقص نور با آهنگی و یا برای هماهنگ کردن با فریم های فیلم ، هر چی فیلم و آهنگ طولانی تر باشن ، تاخیرش بیشتر خودش را نشون میده .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
اون لینکی که دادم ، گفته بود .
نمیدونم از نسخه ی چند از ویژال استودیو استفاده میکنید .
توی نسخه ی 2019 اش ، وقتی برنامه را اجرا کنید ، سمت راستِ ویژال استودیو ، پنجره ی Diagnostic Tools باز میشه . (اگه این پنجره نشون داده نشد ، از قسمت Debug > Windows > Show Diagnostic Tools انتخاب کنید) .
تقریبا قسمت زیرِ این پنجره ، سربرگِ Memory Usage را انتخاب کنید . روی آیکون دوربین که کنارش نوشته Take Snapshot کلیک کنید .
در ستون Heap Size ، روی عددی که در این ستون داده شد ، کلیک کنید .
در پنجره ی باز شده (شبیه تصویر در لینک 15) میاد که نوعِ مورد نظرتون را میتونید جستجو کنید . منتها قبل از جستجوی نوع مورد نظرتون ، کدِ اشیاء و متغییرهایی که از اون نوع هستن ، باید اجرا شده باشن . وگرنه در لیست نمیان (که بدیهی هست) .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
نه .
گفتم فقط حافظه های Unmanaged از اون شی را پاک میکنه . (اون هم خودش پاک نمیکنه ، درخواست پاک کردن را میده) .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
اولا که در کد بالای شما ، فقط برای شیِ nextFrame ، درخواستِ حذفِ حافظه های Unmanaged (ای که برای متغییرهاش اختصاص داده شد) را دادین .
حافظه ی managed را نگفتین که فوری حذف کنه . بنابراین پاک کردن حافظه ی managed ، میمونه تا وقتی که گربگ کالکتور صلاح بدونه که معمولا مواقع لزوم یا مواقع اضطراری هست .
دوما (همونطور که در بالا و هم در پست های قبل گفتم) ، شما هیچ کاری با شیِ خروجیِ متدِ زیر در کدتون نکردین :
کد:nextFrame.ToBitmap()
نگفتین که حافظه ی Bitmap ای که در تایمر قبلی تولید شده بود را اولا نه حافظه ی Unmanaged اش را پاک کردین (چون متد Dispose از این شی را اجرا نکردین) و نه حافظه ی managed اشس را گفتین که فوری پاک کنه (زمانی که بهش نیاز ندارین) .
بنابراین اولا علاوه بر اینکه این شی را به پروپرتیِ pictureBox1.Image اختصاص میدین ، در متغییرِ دیگه ای از این نوع هم اختصاص بدین تا در تایمر بعدی که بهش نیاز ندارین ، Dispose اش کنید :
اون متغییر previouseImageForDisposing ، حتما باید null بشه تا اشاره گرش را از دست بده وگرنه با فراخونیِ متد GC.Collect ، شی اش (یا هر شی ای که اشاره گر داره) ، از حافظه پاک نمیشه .کد:private Image previouseImageForDisposing; private void timer1_Tick(object sender, EventArgs e) { if (this.previouseImageForDisposing != null) { this.previouseImageForDisposing.Dispose(); this.previouseImageForDisposing = null; } using (var nextFrame = capture.QueryFrame()) { if (nextFrame != null) { pictureBox1.Image = nextFrame.ToBitmap(); this.previouseImageForDisposing = pictureBox1.Image; } } }
دوما ، اون متد GC.Collect را باید اجرا کنید تا بگید حافظه ی managed از تمام اشیایی که اشاره گر ندارن ، در اولین فرصت ، پاک بشن (که این کار را هم نکردید) .
دقت کنید که حتما فراخونیِ متدِ GC.Collect را بعد از کدی که متغییرِ previouseImageForDisposing در بالا را null کردیم ، و همچنین بعد از کد زیر در بالا ، انجام بشه :
چون اشاره گرهای به شیِ Bitmap ئه قبلی (که پروپرتیِ pictureBox1.Image و متغییر previouseImageForDisposing که بهش اشاره میکردن) ، باید قبلش از دست بره .کد:pictureBox1.Image = nextFrame.ToBitmap();
لازم هم نیست حتما در هر تایمر ، متد GC.Collect را فراخونی کنید . البته مشکلی نیست و میتونین انجام بدین . اما بهتره که هر وقت حافظه ی کاربر نهایی پر شد یا از اشغال حافظه ، از مقدار خاصی بیشتر شد انجام بدین . چون برای پردازنده ، سربار داره (ولو سربارش ، اندک یا زیاد باشه) .
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
خالی نمیکنه .
شاید با ریفرش کردن ، فرصتی برای گربک کالکتور باشه یا گربگ کالکتور پیامی دریافت کنه که حافظه را اون موقع جمع کنه . مدیریت حافظه ی mmanaged ، فقط توسط گربگ کالکتور انجام میشه .
بالاخره روش اصولی نیست.
توضیح دادم .برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
آخرین ویرایش توسط SajjadKhati در تاریخ 15-09-21 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (15-09-21), vardipoor.m (15-09-21)
|
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
روش Dispose کردنِ شیِ خروجیِ متدِ زیر که در تایمرهای قبلی ایجاد شده بودن :
را در پست قبلی (پست 18) ، گفتم .کد:nextFrame.ToBitmap()
علاوه بر این ، چندین بار دارم میگم که اشیایی که متد Dispose دارن را بعد از استفاده ، Dispose کنید . شیِ myBitmap3 تون هم از این نوع هست و Dispose نکردید .
ضمنا ، نیازی به دو بار اجرای متد GC.Collect نیست . نهایتا میتونید ، یکبار ، اون هم در خط آخر بنویسید . دیگه if و else گذاشتن برای این متد ، معنا نداره .
ضمن اینکه بهتره که این متد را زمانی اجرا کنید که فرضا مقدار اشغالی حافظه ، از یه حدی بیشتر بشه . هر چند مشکلی نداره اما قضیه ی سربار را که گفتم .
چون گربک کالکتور ، فقط حافظه های managed ای را پاک میکنه که اشاره گری بهش وجود نداشته باشه .برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط vardipoor.m برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
وقتی مینویسید :
یعنی شیِ Bitmap ای که از خروجیِ متدِ nextFrame.ToBitmap ایجاد میشه ، اشاره گر داره .کد:pictureBox1.Image = nextFrame.ToBitmap();
اشاره گرش هم پروپرتیِ pictureBox1.Image هست .
بنابراین ، گربگ کالکتور ، حافظه ی managed ئه مربوط به این شی را پاک نمیکنه .
آخرین ویرایش توسط SajjadKhati در تاریخ 15-09-21 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (15-09-21), vardipoor.m (15-09-21), XFXForce (17-09-21)
جا داره از آقا سجاد تشکر کنم به خاطر این همه راهنمایی ممنونم
SajjadKhati (18-09-21)
1 کاربر در حال مشاهده این موضوع. (0 عضو و 1 میهمان)
Bookmarks