Wyciek pamięci fizycznej

0

Cześć.

Piszę program w którym rysuję na bieżąco kursor i go przypisuję aplikacji.
Kursor zmienia rozmiar za pomocą scrOLLa myszki.

kod rysowania wygląda tak:

private void PaintNewCursor()
        {
            Bitmap ba = new Bitmap(SizeCurs, SizeCurs);
            this.Cursor.Dispose();
            Graphics g = Graphics.FromImage(ba);
            Pen p = new Pen(Color.Black);
            g.DrawEllipse(p, 0, 0, SizeCurs, SizeCurs);
            IntPtr ptr = ba.GetHicon();
            this.Cursor = new Cursor(ptr);
            ba.Dispose();
            g.Dispose();
            p.Dispose();
        }

Gdzieś tu jest wyciek pamięci fizycznej. Im większy cursor tym większy wyciek.
Raz nie zauważyłem, że pamięci jest mało i ujrzałem blue screena O_o

Ma ktoś pomysł gdzie tutaj może być wyciek, albo co powoduje takie mocne pożarcie pamięci fizycznej?
Kursor w tej aplikacji często będzie zmieniał swój rozmiar, a więc jest to działanie nieuniknione.
Nie mam pomysłu co by poprawić w tym kodzie.

0

nie Dispose(), tylko using i to do KAŻDEGO obiektu implementującego IDisposable, a nie wybiórczo. przyjrzyj się też w dokumentacji (http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.gethicon.aspx), jak wygląda niszczenie obiektu zwracanego przez GetHicon.

0

Najmocniej dziękuję za odpowiedź, ale nadal mam problem.

kod wygląda tak:

private void PaintNewCursor()
        {
            using (Bitmap ba = new Bitmap(SizeCurs, SizeCurs))
            {
                using(Graphics g  = Graphics.FromImage ( ba ))
                {
                    g.DrawEllipse(new Pen(Color.Black), 0, 0, SizeCurs, SizeCurs);
                }
                IntPtr ptr = ba.GetHicon();
                this.Cursor = new Cursor(ptr);
            }
        }

Po 1.) pamięci nadal ubywa chociaż faktycznie w wolniejszym tempie niż wcześniej.
Po 2.) Program po dłuższej chwili zabawy z wielkością kursora wywala się w tym fragmencie:

IntPtr ptr = ba.GetHicon();

Ale kompilator tylko podświetla tę linię i nie wiadomo o co chodzi. Przypuszczam, że nie może pobrać uchwytu. Tylko dlaczego?

Wielkość kursora ustalam sobie za pomocą scrOLLa myszki.

0

http://msdn.microsoft.com/en-us/library/aa334951.aspx przeczytaj remarks

Ok, ale w jaki sposób to zwolnić?

Zrobiłem w taki sposób:

        private void PaintNewCursor()
        {
            this.Cursor.Dispose();
           
            using (Bitmap ba = new Bitmap(SizeCurs, SizeCurs))
            {
                using(Graphics g  = Graphics.FromImage ( ba ))
                {
                    g.DrawEllipse(p, 0, 0, SizeCurs, SizeCurs);
                }
                IntPtr ptr = ba.GetHicon();
                this.Cursor = new Cursor(ptr);
                Marshal.FreeHGlobal(ptr);

            }
        }

To program po uruchomieniu (pierwsze zdarzenie z tą funkcją) wyświetla błąd "nieprawdiłowe dojście" w linii:

Marshal.FreeHGlobal(ptr);

Z kolei takie coś:

        private void PaintNewCursor()
        {
            this.Cursor.Dispose();
           
            using (Bitmap ba = new Bitmap(SizeCurs, SizeCurs))
            {
                using(Graphics g  = Graphics.FromImage ( ba ))
                {
                    g.DrawEllipse(p, 0, 0, SizeCurs, SizeCurs);
                }
                IntPtr ptr = ba.GetHicon();
                this.Cursor = new Cursor(ptr);
                ptr = IntPtr.Zero;

            }
        }

Nie daje żadnych widocznych rezultatów. Pamięci nadal ubywa, a z czasem program się wywala.

0
ŁF napisał(a):

przyjrzyj się też w dokumentacji (http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.gethicon.aspx), jak wygląda niszczenie obiektu zwracanego przez GetHicon.

!!!!!!

0

Serdecznie dziękuję raz jeszcze.
Wygląda na to, że wszystko ok.

Oto kod jaki napisałem dzięki Waszej pomocy, proszę jeszcze o ocenę przynajmniej pobieżną czy wszystko ok.

[DllImport("user32.dll", CharSet = CharSet.Auto)]
        extern static bool DestroyIcon(IntPtr handle);

IntPtr ptr;
        private void PaintNewCursor()
        {
            this.Cursor.Dispose();
           
            using (Bitmap ba = new Bitmap(SizeCurs, SizeCurs))
            {
                using(Graphics g  = Graphics.FromImage ( ba ))
                {
                    g.DrawEllipse(p, 0, 0, SizeCurs, SizeCurs);
                }
                DestroyIcon(ptr);
                ptr = ba.GetHicon();
                //Icon newIcon = Icon.FromHandle(ptr);
                this.Cursor = new Cursor(ptr);
                //this.Icon = newIcon;
                //DestroyIcon(ptr);

            }
        }

Bardzo dziękuję raz jeszcze.

1 użytkowników online, w tym zalogowanych: 0, gości: 1