Russian Qt Forum

Qt => Общие вопросы => Тема начата: Amigo_sa от Март 17, 2010, 10:48



Название: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 17, 2010, 10:48
Доброго дня!
Мучает меня 1 вопрос на понимание скорее: про фрагментацию памяти в операционной системе. Есть задача - написать высокопроизводительный сервер, который должен работать очень устойчиво и 24 на 7. Точнее она уже решена. Но старшие товарищи до ужаса боятся использовать в ней какие либо сторонние либы вроде Qt, поэтому было написано куча велосипедов - начиная от работы с сетью и заканчиваю машиной состояний. Все написано в статике, с кучей ухищрений.
Собственно вопросы: так ли опасна фрагментация? Неужели менеджеры памяти не умеют освобождать неиспользованные страницы? Насколько оправдано использовать Qt в высокопроизводительных серверных программах?
Буду благодарен, если подскажете какую нибудь книгу или ресурс на тему, как ПРАВИЛЬНО разрабатывать архитектуру, потому что подходов миллион - не могу пока отличить незабудки от ... (как там у классика  :))


Название: Re: Qt vs фрагментация памяти
Отправлено: garryHotDog от Март 17, 2010, 13:29
для какой ОС разработано ПО??? если Win32 то есть хорошая книга "Xp из нутри" или как то так....google ее знает )))


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 17, 2010, 13:36
для какой ОС разработано ПО??? если Win32 то есть хорошая книга "Xp из нутри" или как то так....google ее знает )))
ПО для Линукса, за книгу спасибо)


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:12
Что то странное... Какой вопрос не задам - или сложный или не в тему  ??? Почти никто не отвечает...


Название: Re: Qt vs фрагментация памяти
Отправлено: niXman от Март 18, 2010, 18:19
Цитировать
то то странное... Какой вопрос не задам - или сложный или не в тему   Почти никто не отвечает...
так вы задайте нормальный вопрос.
а то у вас настолько широкая область вопроса, что мне подумалось, что вы сами не знаете что спросить. или просто от скуки задаете вопросы.


Название: Re: Qt vs фрагментация памяти
Отправлено: BigZ от Март 18, 2010, 18:27
Собственно вопросы: так ли опасна фрагментация? Неужели менеджеры памяти не умеют освобождать неиспользованные страницы? Насколько оправдано использовать Qt в высокопроизводительных серверных программах?
Фрагментация опасна тем, что может в нужный момент не оказаться
куска памяти подходящего размера. Менеджеры памяти умеют освобождать память не они не занимаются дефрагментацией памяти. Сервер, который работает в одном процессе не может быть гарантированно отказо-устойчивым, на чём бы он не был написан. Гарантировано, отказо-устойчивым может быть только кластер серверных процессов управляемых несколькими хостами. Если один процесс дохнет, хост поднимает новый. Если дохнет хост, его поднимает другой хост и т.д. Qt- для написания такой конструкции вполне подходит.
 


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 18:31
так вы задайте нормальный вопрос.
а то у вас настолько широкая область вопроса, что мне подумалось, что вы сами не знаете что спросить. или просто от скуки задаете вопросы.

Данный вопрос можно перефразировать:
"Старшие товарищи рисуют картины с помощью масляных красок. Скажите, а возможно ли с помощью фломастеров рисовать картины, насколько это оправдано?"  :)

В принципе можно, только для чего нужны лишние зависимости, для чего в высокопроизводительных серверах использовать Qt?
А про фрагментацию памяти... Ну это опять же от писателя зависит, как он будет с памятью работать.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:34
Цитировать
то то странное... Какой вопрос не задам - или сложный или не в тему   Почти никто не отвечает...
так вы задайте нормальный вопрос.
а то у вас настолько широкая область вопроса, что мне подумалось, что вы сами не знаете что спросить. или просто от скуки задаете вопросы.
Правильная формулировка вопроса - уже залог правильного ответа. Конечно, я сознаю, что спрашиваю не совсем четко. Ситуация такая: руководство не хочет писать высокопроизводительные проги для "сервера 24 на 7" с нагрузкой несколько сот транзакций в секунду, используя сторонние либы, в том числе qt.  Мотивирует это тем, что боится использовать динамику вообще в коде. Я сомневаюсь, что нельзя использовать Qt для таких задач и хотел узнать Ваше мнение.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 18:36
Что значит:
боится использовать динамику вообще в коде.

В смысле разделяемые библиотеки?


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:39
Что значит:
боится использовать динамику вообще в коде.

В смысле разделяемые библиотеки?

Даже больше - любые new, delete, memcpy, и вообще работу с кучей. А так как в сторонных либах в частности в Qt много подобных конструкций - то их всех в сад.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:41
Сервер, который работает в одном процессе не может быть гарантированно отказо-устойчивым, на чём бы он не был написан. Гарантировано, отказо-устойчивым может быть только кластер серверных процессов управляемых несколькими хостами. Если один процесс дохнет, хост поднимает новый. Если дохнет хост, его поднимает другой хост и т.д. Qt- для написания такой конструкции вполне подходит.
Большое спасибо за идею! обязательно погуглю про кластеры!


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 18:43
Даже больше - любые new, delete, memcpy, и вообще работу с кучей. А так как в сторонных либах в частности в Qt много подобных конструкций - то их всех в сад.
Да ладно...  ::)
Может уже написан свой менеджер памяти, который и используется? Как-то я пока не представляю, как можно обойтись без динамической памяти в сложной программе.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:47
Даже больше - любые new, delete, memcpy, и вообще работу с кучей. А так как в сторонных либах в частности в Qt много подобных конструкций - то их всех в сад.
Да ладно...  ::)
Может уже написан свой менеджер памяти, который и используется? Как-то я пока не представляю, как можно обойтись без динамической памяти в сложной программе.

Уваряю, что именно так мне и говорили. Все рабочий потоки созданы на стеке, сокеты, классы с логикой... даже буферы памяти и строки переписаны таким образом, что в конструкторе резервируют свой максимальный размер, а если вдруг ктото допишет байт сверх допустимого, то генерируется эксепшн.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 18:50
в конструкторе резервируют свой максимальный размер....
А ну все таки резервируют, а то ты заставил меня сильно задуматься, как  вы там на стеке все размещаете.  :)


Название: Re: Qt vs фрагментация памяти
Отправлено: BigZ от Март 18, 2010, 18:50
Уваряю, что именно так мне и говорили. Все рабочий потоки созданы на стеке, сокеты, классы с логикой... даже буферы памяти и строки переписаны таким образом, что в конструкторе резервируют свой максимальный размер, а если вдруг ктото допишет байт сверх допустимого, то генерируется эксепшн.
А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?:)


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 18:58
А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?:)
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...


Название: Re: Qt vs фрагментация памяти
Отправлено: BigZ от Март 18, 2010, 19:01
А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?:)
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...
Дело даже не в рекурсии. Может прийти большой кусок данных, который вы будете пытаться пихать в буфер на стеке, чтобы обработать. Ну и соответственно всё рухнет.


Название: Re: Qt vs фрагментация памяти
Отправлено: BigZ от Март 18, 2010, 19:04
А вообще если у старших товарищей есть чёткое понимание, что схема со стеком работает нормально, то Qt вам точно не подойдёт, так как Qt будет точно фрагментировать кучу.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 19:15
А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?:)
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...
Дело даже не в рекурсии. Может прийти большой кусок данных, который вы будете пытаться пихать в буфер на стеке, чтобы обработать. Ну и соответственно всё рухнет.
Ну такая ситуация разруливается на транспортном уровне. Написан протком, в котором установлены максимальные ограничения на пакеты. Чуть что - соединение рвется и в буфер ничего не пишется.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 19:22
Если у вас все буферы на стеке помещаются, то они достаточно малы и к тому-же имеют фиксированный размер. Так о какой фрагментации может идти речь.
Можно выделить кусок памяти (на куче), один раз, в котором и разместить все буферы (пул буферов). И больше никаких new/delete вообще делать не надо.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 18, 2010, 19:33
Если у вас все буферы на стеке помещаются, то они достаточно малы и к тому-же имеют фиксированный размер. Так о какой фрагментации может идти речь.
Можно выделить кусок памяти (на куче), один раз, в котором и разместить все буферы (пул буферов). И больше никаких new/delete вообще делать не надо.

Ну да, любые глобальные данные можно создавать в куче, главное чтобы это было не в цикле обработки запросов. Люди боятся того, что где то в коде Qt, например, incommingConnection будет написан код с new. Ну и в любом используемом классе. Даже в ByteArray кажется не считать данные из сокета без динамики.
Пока, по ответам BigZ, понимаю, что проблема все таки существует...


Название: Re: Qt vs фрагментация памяти
Отправлено: niXman от Март 18, 2010, 19:38
странные требования, даже очень.

немного о своем видении расскажу.
есть у меня два не очень крупных проекта на с++(используется только boost), от 2 до 5 тыщь строк.
оба, работают как сетевые серверы, 24х7. и самое прекрасное, это то, что нет ни одного new/delete.

так же, имею стойкое мнение, что необходимость использовать new/delete возникает крайне редко.
и в большинстве ситуаций, из-за неправильного проектирования.

по поводу Qt в таких проектах, высказывался неоднократно, негативно. но со мной мало кто согласился, форум кютешников все же :)


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 19:41
Ну да, любые глобальные данные можно создавать в куче, главное чтобы это было не в цикле обработки запросов. Люди боятся того, что где то в коде Qt, например, incommingConnection будет написан код с new. Ну и в любом используемом классе. Даже в ByteArray кажется не считать данные из сокета без динамики.
Пока, по ответам BigZ, понимаю, что проблема все таки существует...
Да это не проблема.
Я уже писал, что все зависит от разработчика. И с использованием Qt можно написать сложную программу интенсивно работающую с памятью и никаких проблем не возникнет.
Главное понимать, что делаешь.  ;)
А боязнь использовать штатные средства, просто из-за предрассудков... По моему это перебор.
Всегда можно переопределить операции new/delete для определенных классов и реализовать работу с памятью наиболее оптимально.


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 18, 2010, 21:39
В общем я так вижу что старшие товарищи мыслят верно. По поводу фрагментации памяти - так этот вопрос "исперчен" лет 5 назад (если не 10). Каждому процессу выделяется непрерывное адресное пространство (2 Gb и больше) и ОС занимается всем, в том числе и фрагментацией (нет ходов с GlobalCompact как было до того). Прогаммист может:

- не захватывать большие (100 Mb и больше) блоки "про запас" 
- выравнивать блоки на размер страницы (напр 64K) - небольшая но все же помощь OCу
- (самое эффективное но и самое трудное) - делать swap на диск самому если физической памяти мало.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 18, 2010, 22:53
К сожалению ОС не может заниматься вопросами дефрагментирования в адресном пространстве процесса.
ОС может обеспечить непрерывный адресный кусок памяти для данных и кода процесса размером 2/3Гб (в зависимости от ОС). Как она это будет делать, это проблема ядра, ядро может выгрузить неиспользуемые страницы другого процесса в своп и отдать их этому. Главное, что процесс может спокойно адресовать выделенные ему 2/3Гб.
Дальше процесс рулит своей памятью сам. Он может воспользоваться для этого стандартной библиотекой с ее менеджером памяти, а может этого и не делать.
Почему же ядро не может производить дефрагментацию памяти? А потому, что для определения расположения данных и кода, используются линейные адреса в адресном пространстве процесса. Если мы решили (или это сделал менеджер памяти), что массив data будет лежать по адресу 0x100000, то в дальнейшем этот блок переместить будет нельзя, т.к. ядро не может контролировать сколько раз и где мы сохранили адрес этого массива.
Запутано.  :) Попробую показать на примере (упрощенно):
Код
C++ (Qt)
// array1 располагается сначала памяти, следом находиться array2, потом лежит массив data
char *array1 = new char[ 0x10 ]; // array1 = 0x0000
char *array2 = new char[ 0x10 ]; // array2 = 0x0010
char *data = new char[ 0x100 ]; // data    = 0x0020
 
// Освобождаем array1 и array2
delete []array1;
delete []array2;
 
// Имеем пустой блок сначала памяти 0x0000 - 0x001F, и далее массив data
// Логично было бы подвинуть блок data в начало памяти, но сделать это нельзя, т.к. переменной data присвоенно конкретное значение 0x0020
// и если сдвинуть массив data в начало памяти, то нужно будет откорректировать значение в переменной data на 0x0000.
// А мы может сделать несколько копий этого указателя:
char *ptr = data;
char *var = ptr;
 
// Значит для корректного перемещения массива, нужно исправить и все эти переменные, а вот отследить это практически не возможно.
// Поэтому, в тех языках, где отказались от прямой адресации (указателей), можно применять всякие сборщики мусора, которые могут двигать блоки
// в памяти как угодно, но делается это не средствами ядра ОС, а соответствущими runtime библиотеками.
 


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 18, 2010, 23:44
К сожалению ОС не может заниматься вопросами дефрагментирования в адресном пространстве процесса.
Я понимаю о чем Вы говорите но что сейчас практически дает "(де)фрагментация в адресном пространстве процесса"? Куча не дробится до бесконечности при интенсивных malloc/free. Может быть возникнут проблемы при выделении, скажем, блока 500 Мб но здесь программист сам виноват - такие куски хватать не следует. А в 64 битах - и говорить нечего :-)  Так что особо рулить процессу нечем.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Март 19, 2010, 00:12
BRE, спасибо большое за пример. Намного понятнее стало, почему в шарпо-подобных языках скрыта работа с указателями.  :)
Нагуглил статью (http://bishop3000.livejournal.com/62286.html) про менеджеры памяти, осознаю, что с new, delete и вправду могут быть много проблем. Одна надежда, что Low Fragmentation Heap, возможно поборет фрагментацию внутри "легких" кутешных объектах. Но он не кроссплатформенный...


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 19, 2010, 08:36
Amigo_sa, на самом деле особых проблемы с кучей нет.  :)
Современные менеджеры памяти для уменьшения фрагментации стараются выделять память для разных по размеру блоков в разных областях памяти, например маленькие объекты выделяются с начала хипа, большие с конца. При освобождении блока - проверяется, если рядом с этим блоком находиться свободный блок, то эти блоки будут соединены в один свободный блок. 
Ради интереса попробуй написать небольшую программу, которая будет выделять/освобождать блоки памяти так, что бы через некоторое время программа не могла выполняться из-за фрагментации. Если у тебя это получиться, то ты будешь понимать как с памятью работать не нужно.  :)

Для эффективной работы с хипом нужно понимать как лучше распределять память, а при использовании сторонних библиотек, приходиться разбираться как это делают они. Возможно поэтому, в ваших проектах старшие товарищи и не хотят использовать сторонние библиотеки.
А тонкости есть и в Qt, например при работе с все тем же QVector. Эта тема уже пару раз поднималась на форуме.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 19, 2010, 08:36
Я понимаю о чем Вы говорите но что сейчас практически дает "(де)фрагментация в адресном пространстве процесса"? Куча не дробится до бесконечности при интенсивных malloc/free. Может быть возникнут проблемы при выделении, скажем, блока 500 Мб но здесь программист сам виноват - такие куски хватать не следует. А в 64 битах - и говорить нечего :-)  Так что особо рулить процессу нечем.
Согласен.  :)


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 19, 2010, 13:21
И еще. Я помню в первый раз переделал одну из программ на 64. Ну думаю, сейчас я развернусь! Выкину все swap. наконец-то! Ага, какое там  :). Взял 8Gb (стоит физически 4). Не одним блоком конечно, по частям. Все нормально, 8Gb я получил. Но расчеты которые выполнялись 7 минут (со swap) - стали выполняться 56 минут. Вся силенка ОС ушла в подкачку страниц. Справедливости ради надо отметить что после примерно получаса пиления диска скорость улучшилась - видимо нужные страницы "всплыли". Но в целом это не метод.


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 19, 2010, 14:11
Но в целом это не метод.
Я так понял, что речь идет про системный swap?
Ну так никто не обещал, что будет легко.  ;)
Обещали, что при наличие свободных страниц физической памяти или места в свопе, ядро предоставит процессу физическую память.
Если на машине 4 Gb оперативки, задействовать память свыше этого значения, да еще и чтобы эта память работала также как физическая - вряд ли удастся.  :)
Это уже разработчик должен думать, что бы буферы, с которыми ведется интенсивная работа, всегда находились в физической памяти.



Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 19, 2010, 19:01
Я так понял, что речь идет про системный swap?
Про оба. Я сам делаю swap на диск больших данных, если не влазит - обрабатывается по частям. Попытки "использовать больше памяти" (спихнуть все заботы со  swap'ом на ОС) ничего хорошего не приносят.
Это уже разработчик должен думать, что бы буферы, с которыми ведется интенсивная работа, всегда находились в физической памяти.
Должен. Но это куда как труднее чем писать красивые дефрагментаторы  :)


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Март 19, 2010, 19:16
Это уже разработчик должен думать, что бы буферы, с которыми ведется интенсивная работа, всегда находились в физической памяти.
Должен. Но это куда как труднее чем писать красивые дефрагментаторы  :)
Что трудней, обеспечить что бы размер буфера помещался в физической памяти?


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 19, 2010, 20:35
Что трудней, обеспечить что бы размер буфера помещался в физической памяти?
Обеспечить работу в рамках ограниченного объема памяти (часто заданного пользователем)


Название: Re: Qt vs фрагментация памяти
Отправлено: ритт от Март 19, 2010, 20:51
а звучит тема, звучит...
> Qt vs фрагментация памяти
как "лего vs равномерное распределение средств в гос.учреждениях" :)

упд. поставил строчки ближе во избежание...


Название: Re: Qt vs фрагментация памяти
Отправлено: niXman от Март 19, 2010, 21:19
Igors, детский сад, иначе не скажешь!
прочитав вашу "идею" с 8мью гигами, остается вспоминать лучшее о вас. ибо то о чем вы написали, это антипаттерн "глоб" или "спагетти".
ребятушки, не хочу показаться хамом/выпендрежником, но вы хоть какое-то понятие о культуре программирования имеете?! ваши мысли, напоминают дитёнка, наконец-то убившего котенка! конечно, он рад, столько нового узнал! и наконец-то у него это получилось! но итог его поступка каков?

вы же взрослые люди, должны понимать "то", о чем говорит Igors.

нехочу никого обидеть, просто люблю идеальный код. не хотите, не соглашайтесь со мной. накласть.


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Март 19, 2010, 22:29
Не пойму чего ж я такого страшного сказал?  :) Что мне было интересно проверить работу с большой памятью? Так это каждый бы сделал чтобы удовлетворить свое любопытство. И причем здесь гос.учреждения к которым я не имею никакого отношения последние 20 лет  ???


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Май 04, 2010, 16:53
После перерыва решил вернуться к этой теме:)
Решил написать код, который зафрагментирует нафиг всю память, как мне советовали, начал с более простых примеров, обнаружил полное непонимание механизма выделения памяти.

Написал простой код, который создает в куче элемы пока память не закончится, собирал в релизе.
Код:
#include <new>
#include <iostream>

class T
{
int f;
int g;
int k;
};

int main(int argc, char *argv[])
{
std::cout << sizeof(int);
int count = 0;
try
{
forever
{
[b]double* p = new double;[/b]
count++;
if (!(count % 1000000))
{
std::cout << count << "\n";
}
}
}
catch(std::bad_alloc &ba)
{
std::cout << "bad_alloc ";
std::cout << count;
}
catch(...)
{
std::cout << "unknown " << count;
}
}
В выделенной строчке менял тип создаваемых элементов на int и на T (его размер равен 12). Обнаружил что интов создается 133 млн элементов с копейками, то есть полезной памяти чуть больше пол-гига, в диспетчере задач при этом приложение занимает больше 2-х гигов. Менял тип на double и выделяется теже 133 млн элемов! Полезной памяти уже больше гига получается. Я думал, что new дописывает какую то служебную информацию в блок памяти, поэтому сделал свой тип Т, думая, что чем меньше new будет сделано тем больше полезной памяти выделится. Создалось 88 млн элемов - тот же гиг полезной памяти... 133/88 ~= 12/8...
Вот решил обратиться к общественности с просьбой объяснить, почему так происходит. почему интов выделяется так мало и почему процесс может создать всего чуть больше гига полезной памяти.
Спасибо за ответы.

П.С.  Windows Vista, Visual Studio 2008


Название: Re: Qt vs фрагментация памяти
Отправлено: BRE от Май 04, 2010, 19:22
Посмотри на этот пример:
Код
C++ (Qt)
#include <new>
#include <iostream>
 
template<typename T>
void func()
{
       std::cout << "size type: " << sizeof( T ) << std::endl;
       T *p1 = new T;
       std::cout << p1 << std::endl;
       T *p2 = new T;
       std::cout << p2 << std::endl;
 
       std::cout << "size block: " << ((char*)p2 - (char*)p1) << std::endl;
}
 
struct Type1
{
       int     a;
       int     b;
       int     c;
       int     d;
       int     e;
};
 
struct Type2
{
       double  a;
       double  b;
       double  c;
       double  d;
       double  e;
};
 
int main( int argc, char *argv[] )
{
       func<int>();
       std::cout << "------" << std::endl;
       func<double>();
       std::cout << "------" << std::endl;
       func<Type1>();
       std::cout << "------" << std::endl;
       func<Type2>();
}
 

Он показывает какого размера блок реально выделяется при каждом типе.


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Май 04, 2010, 20:01
Это личное дело ОС какой "размер параграфа", т.е. до какого значения округлять фактический размер выделяемого блока. Если Вы продолжите эксперименты, напр. с размером структуры 1024 байт (а еще лучше 4096), то, полагаю, "КПД" будет близко к единице  :)

Практически всегда накладно делать много распределений маленьких блоков. Такие данные надо распределять chunk'ами (т.е. порциями) так чтобы выделяемый размер был достаточно велик. Эрудиты рекомендуют использовать аллокаторы boost и.т.п. - но это несложно и сделать самому.

Также не следует делать никаких предположений о размере структуры (мол, это 12 байт). Всегда надо использовать sizeof.



 


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Май 05, 2010, 10:05
Посмотри на этот пример:
*********
Он показывает какого размера блок реально выделяется при каждом типе.

Да и вправду, для инта и дабла размеры блоков совпали и равны 16 байт, как раз чтобы заполнить 2 гига, доступных приложению нужно 133 млн элемов...

Поигрался дальше со структурками и с выравниванием, получилось следующее:
1. минимальный выделяемый блок = 16 байт.
2. каждая операция new отбирает 8 байт у блока.
3. у меня получалось что если sizeof(T) + 8 байт на new > 32 то данные выделялись на разных страницах, что в общем не снижает эффективности.
4. при увеличении размера структуры, как и говорил Igors, размер полезной памяти увеличивается и приблизижается к 2-м гигам, как и обещал Рихтер:)

BRE, Igors, Спасибо большое за ответы!


Название: Re: Qt vs фрагментация памяти
Отправлено: Sancho_s_rancho от Май 05, 2010, 10:47
Не совсем понял о чем вообще тред, похоже на какие-то забавы. Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Май 05, 2010, 10:51
Не совсем понял о чем вообще тред, похоже на какие-то забавы. Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned
Тред о том, как работает динамическая память. Надеюсь, что кроме меня еще кому нибудь будет полезно.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Май 05, 2010, 12:06
Подолжаю свои игрушки...
Код:
#include <QList>
#include <new>
#include <iostream>

struct Type1
{
        double     a;
        double     b;
        double     c;
        double     d;  
double e;
};
 
struct Type2
{
        double  a;
        double  b;
        double  c;
        double  d;
        double  e;
double f;
};

class T
{
double f;
double g;
double h;
double d;
int k;
};

int main(int argc, char *argv[])
{
//std::cout << sizeof(T);
forever
{
int count = 0;
QList<void*> pointers;
try
{
forever
{
Type1* p1 = new Type1;
Type2* p2 = new Type2;
T* p3 = new T;

delete p1;
delete p3;

pointers.append(p2);

count++;
if (!(count % 1000000))
{
std::cout << count << "\n";
}
}
}
catch(std::bad_alloc &ba)
{
std::cout << "bad_alloc ";
std::cout << count;
std::cout << "\n";
foreach(void* p, pointers)
{
delete p;
}
pointers.clear();
}
catch(...)
{
std::cout << "unknown " << count;
}
}
}
Этот код фрагментирует примерно половину памяти процесса, что уже очень немало.


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Май 05, 2010, 15:37
Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned
Это не поможет при распределении маленьких блоков (как обсуждалось выше.) "Зато" есть отличные шансы посадить скорость, причем это зависит от конкретного процессора.

Подолжаю свои игрушки...
На мой взгляд пользы от таких игрушек куда больше чем от бестолкового заучивания чужих классов  :)
Интересно было бы пощупать контейнеры STL на предмет их экономичнрсти по сравнении с простым new/malloc. А то шуму много о "шаблонах проектирования" и.т.п. Ну std::vector все просто а вот напр. std::list, std::set - может и пару других - не лишено интереса.


Название: Re: Qt vs фрагментация памяти
Отправлено: Amigo_sa от Май 05, 2010, 16:34
как раз с другом обсуждаем интересную вещь... я прислал ему код означенный выше, но он шарповец и куте установленного не имеет, поменял qLIST на stl::vector и чтоже?? количество элементов выделяемое в моем коде не уменьшается!!! я ради интереса тоде поменял кутешный список на стандартный и получил тот же результат... теперь мучаюсь непониманием, почему же указатели помещенные в список именно кутешный фрагментируют память...


Название: Re: Qt vs фрагментация памяти
Отправлено: whirlwind от Май 05, 2010, 19:24
Бред

1. За счет выравнивания может так оказаться что Type1 и T равны, тогда никакой фрагментации не будет вообще
2. Зачем засовывать указатель в список? Он будет увеличиваться согласно своей стратегии расширения, stl-ный - согласно своей. И все это как-то будет есть память, искажая результаты эксперимента.
3. Попробуйте четко сформулировать, чего вы хотите добиться.
4. Если нужен конкретный результат (а не просто порассуждать с умным видом) то лучше экспериментировать на целевой платформе, с боевым компилятором, библиотеками и, желательно, похожими на боевые исходниками.


Название: Re: Qt vs фрагментация памяти
Отправлено: Igors от Май 07, 2010, 14:55
как раз с другом обсуждаем интересную вещь... я прислал ему код означенный выше, но он шарповец и куте установленного не имеет, поменял qLIST на stl::vector и чтоже?? количество элементов выделяемое в моем коде не уменьшается!!! я ради интереса тоде поменял кутешный список на стандартный и получил тот же результат... теперь мучаюсь непониманием, почему же указатели помещенные в список именно кутешный фрагментируют память...
Для хранения указателей QList, QVector и std::vector - все будут вести себя одинаково - выделять непрерывный массив, может только с разным пулом.