Russian Qt Forum
Ноябрь 25, 2024, 10:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Qt vs фрагментация памяти  (Прочитано 22016 раз)
Amigo_sa
Гость
« Ответ #15 : Март 18, 2010, 18:58 »

А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?Улыбающийся
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...
Записан
BigZ
Гость
« Ответ #16 : Март 18, 2010, 19:01 »

А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?Улыбающийся
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...
Дело даже не в рекурсии. Может прийти большой кусок данных, который вы будете пытаться пихать в буфер на стеке, чтобы обработать. Ну и соответственно всё рухнет.
Записан
BigZ
Гость
« Ответ #17 : Март 18, 2010, 19:04 »

А вообще если у старших товарищей есть чёткое понимание, что схема со стеком работает нормально, то Qt вам точно не подойдёт, так как Qt будет точно фрагментировать кучу.
Записан
Amigo_sa
Гость
« Ответ #18 : Март 18, 2010, 19:15 »

А Stack Overflow старшие товарищи не боятся получить вместо Out of Memory?Улыбающийся
Ну так в коде рекурсии не используется, все относительно линейно, и ресурсов изначально выделено прилично...
Дело даже не в рекурсии. Может прийти большой кусок данных, который вы будете пытаться пихать в буфер на стеке, чтобы обработать. Ну и соответственно всё рухнет.
Ну такая ситуация разруливается на транспортном уровне. Написан протком, в котором установлены максимальные ограничения на пакеты. Чуть что - соединение рвется и в буфер ничего не пишется.
Записан
BRE
Гость
« Ответ #19 : Март 18, 2010, 19:22 »

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

Если у вас все буферы на стеке помещаются, то они достаточно малы и к тому-же имеют фиксированный размер. Так о какой фрагментации может идти речь.
Можно выделить кусок памяти (на куче), один раз, в котором и разместить все буферы (пул буферов). И больше никаких new/delete вообще делать не надо.

Ну да, любые глобальные данные можно создавать в куче, главное чтобы это было не в цикле обработки запросов. Люди боятся того, что где то в коде Qt, например, incommingConnection будет написан код с new. Ну и в любом используемом классе. Даже в ByteArray кажется не считать данные из сокета без динамики.
Пока, по ответам BigZ, понимаю, что проблема все таки существует...
Записан
niXman
Гость
« Ответ #21 : Март 18, 2010, 19:38 »

странные требования, даже очень.

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

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

по поводу Qt в таких проектах, высказывался неоднократно, негативно. но со мной мало кто согласился, форум кютешников все же Улыбающийся
Записан
BRE
Гость
« Ответ #22 : Март 18, 2010, 19:41 »

Ну да, любые глобальные данные можно создавать в куче, главное чтобы это было не в цикле обработки запросов. Люди боятся того, что где то в коде Qt, например, incommingConnection будет написан код с new. Ну и в любом используемом классе. Даже в ByteArray кажется не считать данные из сокета без динамики.
Пока, по ответам BigZ, понимаю, что проблема все таки существует...
Да это не проблема.
Я уже писал, что все зависит от разработчика. И с использованием Qt можно написать сложную программу интенсивно работающую с памятью и никаких проблем не возникнет.
Главное понимать, что делаешь.  Подмигивающий
А боязнь использовать штатные средства, просто из-за предрассудков... По моему это перебор.
Всегда можно переопределить операции new/delete для определенных классов и реализовать работу с памятью наиболее оптимально.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Март 18, 2010, 21:39 »

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

- не захватывать большие (100 Mb и больше) блоки "про запас" 
- выравнивать блоки на размер страницы (напр 64K) - небольшая но все же помощь OCу
- (самое эффективное но и самое трудное) - делать swap на диск самому если физической памяти мало.
Записан
BRE
Гость
« Ответ #24 : Март 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 библиотеками.
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Март 18, 2010, 23:44 »

К сожалению ОС не может заниматься вопросами дефрагментирования в адресном пространстве процесса.
Я понимаю о чем Вы говорите но что сейчас практически дает "(де)фрагментация в адресном пространстве процесса"? Куча не дробится до бесконечности при интенсивных malloc/free. Может быть возникнут проблемы при выделении, скажем, блока 500 Мб но здесь программист сам виноват - такие куски хватать не следует. А в 64 битах - и говорить нечего :-)  Так что особо рулить процессу нечем.
Записан
Amigo_sa
Гость
« Ответ #26 : Март 19, 2010, 00:12 »

BRE, спасибо большое за пример. Намного понятнее стало, почему в шарпо-подобных языках скрыта работа с указателями.  Улыбающийся
Нагуглил статью про менеджеры памяти, осознаю, что с new, delete и вправду могут быть много проблем. Одна надежда, что Low Fragmentation Heap, возможно поборет фрагментацию внутри "легких" кутешных объектах. Но он не кроссплатформенный...
Записан
BRE
Гость
« Ответ #27 : Март 19, 2010, 08:36 »

Amigo_sa, на самом деле особых проблемы с кучей нет.  Улыбающийся
Современные менеджеры памяти для уменьшения фрагментации стараются выделять память для разных по размеру блоков в разных областях памяти, например маленькие объекты выделяются с начала хипа, большие с конца. При освобождении блока - проверяется, если рядом с этим блоком находиться свободный блок, то эти блоки будут соединены в один свободный блок. 
Ради интереса попробуй написать небольшую программу, которая будет выделять/освобождать блоки памяти так, что бы через некоторое время программа не могла выполняться из-за фрагментации. Если у тебя это получиться, то ты будешь понимать как с памятью работать не нужно.  Улыбающийся

Для эффективной работы с хипом нужно понимать как лучше распределять память, а при использовании сторонних библиотек, приходиться разбираться как это делают они. Возможно поэтому, в ваших проектах старшие товарищи и не хотят использовать сторонние библиотеки.
А тонкости есть и в Qt, например при работе с все тем же QVector. Эта тема уже пару раз поднималась на форуме.
Записан
BRE
Гость
« Ответ #28 : Март 19, 2010, 08:36 »

Я понимаю о чем Вы говорите но что сейчас практически дает "(де)фрагментация в адресном пространстве процесса"? Куча не дробится до бесконечности при интенсивных malloc/free. Может быть возникнут проблемы при выделении, скажем, блока 500 Мб но здесь программист сам виноват - такие куски хватать не следует. А в 64 битах - и говорить нечего :-)  Так что особо рулить процессу нечем.
Согласен.  Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #29 : Март 19, 2010, 13:21 »

И еще. Я помню в первый раз переделал одну из программ на 64. Ну думаю, сейчас я развернусь! Выкину все swap. наконец-то! Ага, какое там  Улыбающийся. Взял 8Gb (стоит физически 4). Не одним блоком конечно, по частям. Все нормально, 8Gb я получил. Но расчеты которые выполнялись 7 минут (со swap) - стали выполняться 56 минут. Вся силенка ОС ушла в подкачку страниц. Справедливости ради надо отметить что после примерно получаса пиления диска скорость улучшилась - видимо нужные страницы "всплыли". Но в целом это не метод.
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.168 секунд. Запросов: 23.