Russian Qt Forum

Qt => Общие вопросы => Тема начата: RedDog от Февраль 22, 2020, 19:14



Название: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 22, 2020, 19:14
Есть каскад всяческих логик от получения QByteArray из сокета, пред обработки его, промежуточной, пост обработки и далее укладки на диск и/или в БД.
Все это дело распараллелено где через помещение обработчика в QThread, где через QtConcurrent::run()
Где то пару раз в секунду в сокеты приходит 2-2.5мб данных, примерно столько объёма же доходит и до записи этого всего на диск.
В промежуточной логике обработки есть некоторое кеширование ~20 пакетов.
Прога за 3-4 часа по системному монитору распухает в памяти на 500 мб. При сбросе кеша на диск уменьшения жора памяти не наблюдается.
В линуксовой сборке пользуюсь malloc_trim(), он помогает, увидеть более приемлемые цифы жора памяти, чуть меньше 200мб, без видимого роста.

Вопрос: какие методы можно применить для уменьшения фрагментации, при условии, что на каждом этапе обработки нужна своя "копия" QByteArray?
PS: если не так сильно параллелить через QtConcurrent::run(), тогда памяти меньше потребляется.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Igors от Февраль 23, 2020, 10:50
Вопрос: какие методы можно применить для уменьшения фрагментации, при условии, что на каждом этапе обработки нужна своя "копия" QByteArray?
Для начала убедиться что проблема именно в фрагментации собрав статистику QBytArray.size(). Вообще 500 метров - по нынешним временам дело рядовое. Сама борьба с фрагментацией всегда сводится к одному - выделять блоки одинакового размера, напр кратные 4K (только не 4096, а чуть меньше, напр 4000). Соорудить что-то типа QAlignedByteArray


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 23, 2020, 17:35
Утечек valgrind не показывает. malloc_trim сбрасывает у приложения память.
Размеры QBytArray как написал выше, не превышают 2.5мб.
Я правильно понимаю, что надо делать QBytArray::reserve(кратно 4000) ?
Есть сомнения, что "внутри" Qt-шных EventLoop-ов они такое же состояние по резервированию сохранят.
PS: майн кампф за память идет от необходимости запускать подобных процессов довольно много (форком или вручную, пока не решил), думаю за 100 штук легко перевалит.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: qate от Февраль 23, 2020, 23:04
а зачем запускать именно _отдельных_ процессов 100 шт, а не в этом же одном все нужное сделать  ?


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 23, 2020, 23:16
а зачем запускать именно _отдельных_ процессов 100 шт, а не в этом же одном все нужное сделать  ?
Архитектура юзаемой сторонней библиотеки такова, что надо каждый вызов ее апи делать отдельным потоком, а создавать 100500 потоков, которые будут 95% времени на локах висеть, в одном приложении, я считаю моветон.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: qate от Февраль 24, 2020, 10:04
т.е. предполагается, что 100500 процессов будут эффективнее 100500 потоков ?


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Igors от Февраль 24, 2020, 12:37
Размеры QBytArray как написал выше, не превышают 2.5мб.
Я правильно понимаю, что надо делать QBytArray::reserve(кратно 4000) ?
Повторюсь - начните со сбора/печати статистики, часто это наталкивает на нужные мысли и почти всегда экономит массу времени

Есть сомнения, что "внутри" Qt-шных EventLoop-ов они такое же состояние по резервированию сохранят.
В смысле при передаче через слот/сигнал? Ну может и так, в худшем случае придется resize (а не reserve) и хранить размер. Неприятно но не смертельно

PS: майн кампф за память идет от необходимости запускать подобных процессов довольно много (форком или вручную, пока не решил), думаю за 100 штук легко перевалит.
Это уже др вопрос или тема


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 24, 2020, 16:29
т.е. предполагается, что 100500 процессов будут эффективнее 100500 потоков ?
каждый из 100500 процессов будет содержать кол-во потоков, равное количеству потоков процессора, т.е 100500/CoresCount.
И второй момент, эти 100500 процессов можно будет разместить на разных тачках.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Авварон от Февраль 24, 2020, 16:33
И второй момент, эти 100500 процессов можно будет разместить на разных тачках.

Сжечь еретика!


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Авварон от Февраль 24, 2020, 16:35
По сабжу - смотреть состимным монитором гиблое дело, он показывает выделенные _страницы_ памяти (которые не факт что вообще юзаются и еще и отдаютс назад очень лениво).
Советую посмотреть нормальной тулзой на аллокации\утечки.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 24, 2020, 17:02
И второй момент, эти 100500 процессов можно будет разместить на разных тачках.

Сжечь еретика!
Здесь так не принято? В смысле распределенные приложения.

Утечек нет, валгринд молчит.
Какие есть еще тулзы на посмотреть?


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Old от Февраль 24, 2020, 17:21
Утечек нет, валгринд молчит.
Какие есть еще тулзы на посмотреть?
Не понятно что вы хотите посмотреть.
Судя по всему у вас нет никаких проблем. Запустите приложение не на 3 часа, а на сутки. Если количество потребляемой памяти не увеличится, то все хорошо. Распределенная память у вас используется повторно, иначе бы она все время увеличивалась.

Не нужно бороться с фрагментацией адресного пространства, на 64 битных платформах это потеряло всякий смысл. На 32 битах еще приходилось - 4 Гб адресного пространства могло не хватать, но на 64... не выработаете. :)
И да, занятое адресное пространство != занятая память.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 24, 2020, 19:05
Запустите приложение не на 3 часа, а на сутки. Если количество потребляемой памяти не увеличится, то все хорошо. Распределенная память у вас используется повторно, иначе бы она все время увеличивалась
Я так и сделал. За 8 часов работы (при мне) оно "отжирало" 250-300мб, после ночи, с утра 550-600мб.
Щас на праздники оставил, но правда malloc_trim() там еще работает.

И по большому то счету дело в том, что там логики то особой не накручено, никуда данные в память не кешируются (не писал такого) в таких объемах, как показывает диспетчер.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Old от Февраль 24, 2020, 19:20
Щас на праздники оставил, но правда malloc_trim() там еще работает.
malloc_trim ничего не дефрагментирует, он отдает ядру не занятую память вверху кучи, если она там есть.
Если блок вверху занят, ничего не освободиться, хотя в начале/середине кучи может быть много свободных блоков.



Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 24, 2020, 19:27
malloc_trim ничего не дефрагментирует, он отдает ядру не занятую память вверху кучи, если она там есть.
Это я понимаю. С ним диспетчер задач красивей выглядит. )))


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 25, 2020, 19:24
Докладываю: QBytArray::reserve(кратно 4000) помогло.
Проверил capacity после передачи через сигнал-слот сохраняется.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Old от Февраль 25, 2020, 19:35
Докладываю: QBytArray::reserve(кратно 4000) помогло.
Проверил capacity после передачи через сигнал-слот сохраняется.
Помогло с чем? :)

Если вы знаете конкретный размер для QByteArray, то и используйте его, для чего увеличивать этот размер до кратного 4000? Просто что бы память потратить? :)

Вы работаете с непрерывным адресным пространством, там нет никаких физических страниц.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: RedDog от Февраль 25, 2020, 19:41
Помогло с чем? :)
С тем, что количество зарезервированной памяти не увеличивается.


Название: Re: QByteArray между потоков через сигналы-слоты фрагментирует память
Отправлено: Old от Февраль 25, 2020, 19:46
С тем, что количество зарезервированной памяти не увеличивается.
Попробуйте устанавливать точные размеры (вместо кратных 4000) и тоже не будет увеличиваться. :)