Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.08.2012, 15:51   #1
mr_cipher
Пользователь
 
Регистрация: 05.03.2012
Сообщений: 29
По умолчанию Проблема с утечкой памяти

Здравствуйте!
Я в C# начинающий.
Есть такой вот код выполняющийся в бесконечном цикле в отдельном потоке:
Код:

                        ms_pic.Position = 0;
                        GetImage().Save(ms_pic, System.Drawing.Imaging.ImageFormat.Jpeg);
                        int height = GetImage().Height;
                        //byte[] pic = System.Text.Encoding.ASCII.GetBytes(GetImage().ToString());
                        byte[] CaptureImageBuff = ms_pic.ToArray();
                        UDPSocket_pic.SendBufferSize = CaptureImageBuff.Length;
                        //UDPSocket_pic.ReceiveBufferSize = CaptureImageBuff.Length;
                        UDPSocket_pic.SendTo(CaptureImageBuff, sendpt_pic);
                        CaptureImageBuff = null;
Проблема в том, что при запуске программы - это вот кусочек отжирает память понемножку. Если эти строки комментировать - память не съедается.
Пробовал
Код:
GC.Collect()
- но не помогло.
Подскажите, как правильно очищать память в данном случае.

Забыл вот это (объявление и инициализация):
Код:
IPEndPoint sendpt_pic = null;
        MemoryStream ms_pic = null;
        Socket UDPSocket_pic = null;
if (sendpt_pic == null)
            {
                sendpt_pic = new IPEndPoint(IPAddress.Parse(GetIPAddress()), GetIPPortNmbr());
            }
            if (ms_pic == null)
            {
                ms_pic = new MemoryStream();
            }

            if (UDPSocket_pic==null)
            {
                UDPSocket_pic = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }

Последний раз редактировалось mr_cipher; 15.08.2012 в 15:52. Причина: добавил инициализацию
mr_cipher вне форума Ответить с цитированием
Старый 15.08.2012, 17:59   #2
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Код:
 GetImage()
Почти уверен, что возвращаемый этой функцией объект нужно диспозить...
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 15.08.2012, 18:47   #3
mr_cipher
Пользователь
 
Регистрация: 05.03.2012
Сообщений: 29
По умолчанию

Цитата:
Сообщение от Selestis Посмотреть сообщение
Код:
 GetImage()
Почти уверен, что возвращаемый этой функцией объект нужно диспозить...
Пробовал.
Диспосил и mc_pic, и объект возвращаемый GetImage(), и делал массив статичным (фиксированного размера).
Но проблему так и не решил.

Может кто подскажет- какими средствами можно подглядеть какому объекту сколько памяти выделено (некоторую диаграмму выделения памяти) и моменты выделения.
mr_cipher вне форума Ответить с цитированием
Старый 15.08.2012, 19:29   #4
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Ну как бы проверить-то нетрудно: комментируйте поочерёдно все участвующие в цикле объекты и смотрите, есть ли утечка.
И, если не трудно, выложите код GetImage....
Изобретатель велосипедов

Последний раз редактировалось Selestis; 15.08.2012 в 19:33.
Selestis вне форума Ответить с цитированием
Старый 15.08.2012, 21:23   #5
Guy
Форумчанин
 
Регистрация: 15.12.2010
Сообщений: 398
По умолчанию

попробуй ms_pic не создавать каждый раз новый а используя старый перезатирая.
А так лучше профайлером убедится что течёт.
Guy вне форума Ответить с цитированием
Старый 20.08.2012, 10:52   #6
mr_cipher
Пользователь
 
Регистрация: 05.03.2012
Сообщений: 29
По умолчанию

Код:
delegate void CameraFunction();
        CameraFunction dcamstp = null;
        CameraFunction dcamcont = null;

        private Image GetImage()
        {
            Image result = null;
            if (dcamstp == null)
            {
                dcamstp = new CameraFunction(CameraStop);
            }
            {
                dcamcont = new CameraFunction(CameraContinue);
            }
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(dcamstp);
                    result = pictureBox1.Image;
                    this.Invoke(dcamcont);
                }
                else
                {
                    CameraStop();
                    result = pictureBox1.Image;
                    CameraContinue();
                }
            }
            catch(Exception e)
            {
                //MessageBox.Show( e.ToString() );
            }
            return result;
        }
Перетирать тоже пробовал.
Что есть "профайлер" и с чем его едят?
mr_cipher вне форума Ответить с цитированием
Старый 20.08.2012, 12:31   #7
Guy
Форумчанин
 
Регистрация: 15.12.2010
Сообщений: 398
По умолчанию

Профайлеров не мало... Но могу посоветовать :

memprofiler
Вот им триальной 30 дневной версией. А что такое профайлер ты легко найдёшь в тырнете
Guy вне форума Ответить с цитированием
Старый 27.08.2012, 18:29   #8
mr_cipher
Пользователь
 
Регистрация: 05.03.2012
Сообщений: 29
По умолчанию

Итак, потратил недельку времени, чтобы разобраться с профайлером. Прикольная штука.
От части мне это помогло, но запутало меня ещё больше.
Исследовал влияние каждой строки кода на память.
В профайлере, в любой ситуации, я наблюдаю график Total bytes практичеки на постоянном уровне (около 780 тыс. байт) в течение всего времени работы программы (присутствуют лишь небольшие колебания вверх-вниз, среднее значение постоянно).
При этом, в Диспетчере задач кушаемая память продолжает неуклонно расти.

Кстати, код немного переделал (суть не изменилась, только объявление всех переменных вынес за пределы цикла):
Код:
ms_pic.Position = 0;
                        img = GetImage();
                        img.Save(ms_pic, System.Drawing.Imaging.ImageFormat.Jpeg);
                        height = img.Height;
                        //byte[] pic = System.Text.Encoding.ASCII.GetBytes(GetImage().ToString());
                        CaptureImageBuff = ms_pic.ToArray();
                        UDPSocket_pic.SendBufferSize = CaptureImageBuff.Length;
                        //UDPSocket_pic.ReceiveBufferSize = CaptureImageBuff.Length;
                        UDPSocket_pic.SendTo(CaptureImageBuff, sendpt_pic);
Собсно вопрос к знатокам потаённых глубин С#:
Что течёт то??? Я боюсь, что когда объём съедаемой памяти достигнет 2 Гб программа просто вылетит.
mr_cipher вне форума Ответить с цитированием
Старый 27.08.2012, 20:35   #9
Guy
Форумчанин
 
Регистрация: 15.12.2010
Сообщений: 398
По умолчанию

Сделай snapshot перед запуском скриншотера своего, включи и доводя до прироста в 50-100% памяти сделай промежуточных 2-а snapshot-а и последний перед закртием. Затем сохрани, заархивируй и выложы или мне кинь я посмотрю

При условии что ты делаешь все тем профайлером который я тебе кинул.
Guy вне форума Ответить с цитированием
Старый 28.08.2012, 13:59   #10
mr_cipher
Пользователь
 
Регистрация: 05.03.2012
Сообщений: 29
По умолчанию

Не туда смотрел.
(ТОлько это не скриншоттер - картинки ловлю с вебки.)
Косяк зарыт тут:
Код:
img = GetImage();
Переделал вот так:
Код:
private Image GetImage()
        {
            Image result = null;
            if (dgtimg == null)
            {
                dgtimg = new dGetimage(GetImage);
            }
            if (dcamstp == null)
            {
                dcamstp = new CameraFunction(CameraStop);
            }
            {
                dcamcont = new CameraFunction(CameraContinue);
            }
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(dcamstp);
                    //result = pictureBox1.Image;
                    result = (Image)this.Invoke(dgtimg);
                    this.Invoke(dcamcont);
                }
                else
                {
                    CameraStop();
                    result = pictureBox1.Image;
                    CameraContinue();
                }
            }
            catch(Exception /*e*/)
            {
                //MessageBox.Show( e.ToString() );
            }
            return result;
        }
Не помогло.
mr_cipher вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с переполнением памяти maxeebon Общие вопросы Delphi 4 19.08.2011 22:09
Проблема с освобождением памяти Vyachek2010 Общие вопросы Delphi 15 08.02.2011 17:05
Проблема с утечкой памяти ExPeL Win Api 4 21.10.2010 22:13
Проблема с виделением памяти! FreTFuL Общие вопросы C/C++ 1 07.05.2010 20:23
самописный assert: проблема с утечкой памяти) sashonk Общие вопросы C/C++ 2 26.04.2010 15:58