Название: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 13:20 Столкнулся с проблемой утечки памяти при обработке событий поставленных в очередь через postEvent.
Описание: Есть объект обработчик сообщений. Есть функция которая посылает сообщения объекту обработчику при помощи QCoreApplication::postEvent. После обработки всех сообщений утекает некоторое количество памяти. Как я это определил: Очень просто, запускаю приложение без отправки сообщения - объем памяти занимаемый приложением V. Запускаю приложение с отправкой n сообщений, объем памяти - Vn (>V). Запускаю приложение с отправкой n1 сообщений, объем памяти - Vn1 (>Vn). При этом в результате тестов выяснил следующие факты: Объем утекшей памяти зависит от продолжительности обработки каждого сообщения (usleep в обработчике). Не важно в каком потоке отправлять сообщения. Объекты сообщений однозначно удаляются. Тестировал на Win7 x64 и Linux x64. Текст программы в приложении. Прошу помощи. Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 15:07 Если удаляется, значит всё в порядке. Кода вы не привели, смотреть не на что.
Если имеется N созданий и N удалений, всё в порядке. Менеджер памяти на Windows не забирает сразу свободную память. Она продолжает числиться за приложением до тех пор, пока менеджеру не понадобится. Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 18:11 Если удаляется, значит всё в порядке. Кода вы не привели, смотреть не на что. Код в приложении. Если имеется N созданий и N удалений, всё в порядке. Менеджер памяти на Windows не забирает сразу свободную память. Она продолжает числиться за приложением до тех пор, пока менеджеру не понадобится. Про менеджер я понял, но память течет пропорционально времени обработки сообщений и количеству этих сообщений. Если задать достаточное количество, то можно легко уйти в своп. Для контроля количества объектов сообщений используется счетчик. Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 18:19 А где здесь удаление? я что то не вижу delete.
Название: Re: postEvent - Утечка памяти Отправлено: Old от Октябрь 05, 2014, 18:25 Ну так все согласно вашим желаниям. :)
Согласно вашему коду, вы вначале создаете пять миллионов объектов класса Event, а только потом начинаете их обрабатывать (при запуске exec). Т.е. память будет освобождаться по мере их обработки. Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 18:39 update: уже нашёл сам. Диспетчер сам удаляет. to Dodge - В вашем примере всё просто. Из-за задержки при обработке, скорость обработки очереди ОЧЕНЬ ОЧЕНЬ низкая. Уберите оттуда задержку и у вас память будет чиститься при нормальных скоростях. Вы ддосите диспетчер event'ов и сознательно замедляете его обработку при помощи usleep - в этот момент вся программа стоит. Т.е. обработка 5 миллионов записей будет произведена за 5 000 000 * задержку(50 микросекунд) * вызов QObject::event * работу диспетчера * на удаление event'a. Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 19:05 Обсалютно со всеми согласен.
Но есть одно но: объем памяти до обработки и после различается, хотя по логике должен быть одинаковый. Задержку я внес намерено, если изменять значение задержки, объем откушанной памяти после окончания обработки изменяется. После обработки прилоение занимает гораздо больше памяти чем чем до. Меня это и смущает. Причем очевидно это не связано с особенностями диспетчера памяти конкретной ОС, т.к. под вин и линукс результат воспроизводится. Название: Re: postEvent - Утечка памяти Отправлено: Old от Октябрь 05, 2014, 19:14 Но есть одно но: объем памяти до обработки и после различается, хотя по логике должен быть одинаковый. Давайте разберемся, что для вас до обработки и что после. В каких местах вы это замеряете?Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 19:20 Ну это имеет место быть, с 1 мб памяти увеличивается до 9 после обработки.
Собственно мой тестовый проект сейчас обрабатывает 500000 и я вам точно скажу сколько чего осталось :D update: Ну, все объекты типа myEvent удалились успешно и освобождённо взмыли в небеса. А почему увеличивается размер - я думаю что это диспетчер увеличил зарезервированное место под очередь. Собственно других объяснений я не вижу :) Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 21:21 ... Под Linux видно зарезервированную память и реально используемою. Увеличивается реально используемый объем. И как я уже писал, объем сильно зависит от скорости обработки каждого сообщения, если их посылать в бесконечном цикле, то рано или поздно память заполняется на столько, на сколько это возможно.А почему увеличивается размер - я думаю что это диспетчер увеличил зарезервированное место под очередь. Собственно других объяснений я не вижу :) Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 21:25 Но есть одно но: объем памяти до обработки и после различается, хотя по логике должен быть одинаковый. Давайте разберемся, что для вас до обработки и что после. В каких местах вы это замеряете?После чего раскоментировал код, собрал и запустил приложение, дождался когда последнее сообщение будет удалено и замерил снова. Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 21:51 Если запускать в бесконечном, то обрабатываться они не будут вообще. Ибо цикл сообщений не будет запущен :D Потому будет простая перегрузка.
Зависимость от времени неявная. Завтра потестю с увеличенной задержкой, но мне кажется бред :D Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 05, 2014, 22:20 Если запускать в бесконечном, то обрабатываться они не будут вообще. Ибо цикл сообщений не будет запущен :D Потому будет простая перегрузка. Чтобы этого избежать, нужно запустить функцию в параллельном потоке. Для этого в файле достаточно раскомментить строчку:Код: //QtConcurrent::run( spam, &recevier, 5000000 ); и закоментить синхронный вызов соответственно. Зависимость от времени неявная. Завтра потестю с увеличенной задержкой, но мне кажется бред :D Такое ощущение, что в меня пытаетесь уличить во лжи. Я не вру, честное слово. ))Название: Re: postEvent - Утечка памяти Отправлено: Bepec от Октябрь 05, 2014, 23:56 Ммм... Вы можете заблуждаться :) А там святое дело )
Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 06, 2014, 00:46 Ммм... Вы можете заблуждаться :) А там святое дело ) Ага, тут вариантов не много, либо я что-то не так делаю, либо в кутэ баг. ))Название: Re: postEvent - Утечка памяти Отправлено: Old от Октябрь 06, 2014, 06:46 Я уже писал, что я замерил память в запущенном приложении, в котором отправка сообщений не производилась (просто закоментировал код, который формирует сообщения). Вы не хотите замечать, что у вас помимо отправки происходит еще и создание объектов сообщений, причем всех сразу.А это минимум 24 байта на объект Event -> 24 * 5000000 = 120 Мб Плюс указатели в очереди на эти объекты, на 32 битной платформе, еще 20 Мб. На размещение этих объектов событий у ядра получена память (вы смотрите именно на нее), но после удаления всех объектов, память кучи может не возвращаться ядру, а использоваться для дальнейшего выделения. Название: Re: postEvent - Утечка памяти Отправлено: Dodge от Октябрь 06, 2014, 20:25 Я уже писал, что я замерил память в запущенном приложении, в котором отправка сообщений не производилась (просто закоментировал код, который формирует сообщения). Вы не хотите замечать, что у вас помимо отправки происходит еще и создание объектов сообщений, причем всех сразу.А это минимум 24 байта на объект Event -> 24 * 5000000 = 120 Мб Плюс указатели в очереди на эти объекты, на 32 битной платформе, еще 20 Мб. На размещение этих объектов событий у ядра получена память (вы смотрите именно на нее), но после удаления всех объектов, память кучи может не возвращаться ядру, а использоваться для дальнейшего выделения. Во первых, если следовать Вашей логике, то при генерации сообщений в бесконечном цикле, объем используемой памяти должен стабилизироваться на конкретном значении, которое будет зависеть от скорости их обработки. Но по факту это не так, происходит постоянный прирост используемой памяти. Во вторых, практически любой менеджер задач под линукс (я использовал htop), показывает объем реально занимаемой памяти и объем зарезервированной памяти. Так вот прирост отмечается именно в реально используемой. Отсюда я и сделал вывод об утечке. Название: Re: postEvent - Утечка памяти Отправлено: Old от Октябрь 06, 2014, 20:34 Попробуйте после первой обработки всех событий запустить и обработать еще столько же событий. С замерами памяти до и после.
И еще раз хочу отметить, что пока выполняется функция spam сообщения не обрабатываются, цикл обработки сообщений еще не запущен. Поэтому сообщения просто набиваются в очередь, поэтому расход памяти только увеличивается. Во вторых, практически любой менеджер задач под линукс (я использовал htop), показывает объем реально занимаемой памяти и объем зарезервированной памяти. Нет, они показывают объем распределенной виртуальной и физической памяти. Физическая память распределятся под кучу, в которой и сохраняются объекты Event. В дальнейшем эта память освобождается и может повторно использоваться для хранения других объектов/данных.Физическая память распределяется процессу, он там может расположить кучу для хранения данных, но куча эта может быть свободной для хранения данных процесса. Именно поэтому на форуме 100500 раз писали, что не нужно пытаться отследить состояние кучи по системных мониторам. |