Russian Qt Forum

Qt => Общие вопросы => Тема начата: Unnamed_Hero от Январь 28, 2010, 15:31



Название: Как Qt работает с памятью и вообще про память
Отправлено: Unnamed_Hero от Январь 28, 2010, 15:31
Посоветуйте, что можно почитать про организацию работы с памятью, её эффективного использования, как Qt работает с памятью.
Есть несколько вопросов-утверждений. Насколько они верны? Что можно почитать, чтобы не возникали подобные вопросы?

-У программы есть стек, туда пишутся все локальные переменные функций. запустилась функция - в стеке выделились необходимые блоки памяти для хранения переменных. функция отработала - память помечена как свободная. Туда могут быть помещены новый данные.
-Во время работы программы он может только расти, но не уменьшаться.
-Память из стека возвращается в систему только по закрытию программы.
-Qt'шные треды используют свой стек (если верить дизайнеру) - значит ли, что после отработки треда память, выделенная для стека треда, возвратиться в систему, или всё же стек для треда создаётся внутри стека программы?


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Akaiten от Январь 28, 2010, 16:59
У каждого потока есть свой собственный стек. Размер стека можно указать при создании потока, у главного потока размер стека берётся из заголовка exe файла. Обычно стек используется для передачи переменных функциям, возврата из функций и выделения памяти под временные переменные (например, локальные переменные функции). При заполнении стека соответственно оставшееся свободное место в стеке уменьшается, при освобождении - соответственно увеличивается. Собственно все эти операции просто изменение указателя стека (специального регистра sp). По крайней мере под Windows изначально стеку физическая память не выделяется, она выделяется по мере обращения к ней (выделяются страницы памяти). Память, выделенная по стек, освобождается при завершении потока. Но если поток был прерван другим потоком, память не освобождается. Вся память выделенная процессу освобождается при завершении процесса.

Добавлено 17:04.
Для эффективной работы с памятью необходимо учитывать:
  • Аппаратную составляющую. Здесь можно почитать, например, организацию иерархии памяти в процессоре i386 :)
  • Операционную систему. Для Windows можно почитать Inside Microsoft Windows 2000 by David A. Solomon and Mark E. Russinovich, 3 ed, 2000
  • Средства для работы с памятью языка программирования. Первое что нагуглил (http://www.ibm.com/developerworks/linux/library/l-memory/) :)


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Amigo_sa от Январь 28, 2010, 17:17
Про организацию работы с памятью можно очень много всего написать. Статей и учебников куча. Qt - обычная библиотека, она работает с памятью точно так же как и любая C++ программа.

Память для переменных программы можно выделить как в стеке (http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%BE%D0%B2), так и в куче  (http://ru.wikipedia.org/wiki/%D0%9A%D1%83%D1%87%D0%B0_%28%D0%BD%D0%B5%D1%80%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C%29)(динамическая память). Первая память быстрая, индексируемая, но ограничена размером (по умолчанию размер стека в винде 1мб), динамическая память медленнее, с ней можно работать лишь с помощью указателей. Соответственно, мелкие локальные переменные следует создавать на стеке, а крупные объекты либо те, которые должны существовать длительное время - в куче.

-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
-не верно.
-Память для статических объектов освобождается после завершения области видимости, для динамической - вызовом оператора delete.
-В тредах ессно свой стек, и свой цикл обработки сообщений.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Январь 28, 2010, 17:40
-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
??? Стек один на весь процесс. Какой свой стек для каждой функции?

-В тредах ессно свой стек, и свой цикл обработки сообщений.
Только если его запустить, а можно и не запускать...


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Amigo_sa от Январь 28, 2010, 17:59
-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
??? Стек один на весь процесс. Какой свой стек для каждой функции?
Да конечно, извините, я не верно сформулировал. Я имел в виду, что при вызове функции в стек помещается адрес вызова, параметры и дальше он разворачивается ничего не зная о том, кто его вызвал. А при завершении, стек очищается.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Unnamed_Hero от Январь 29, 2010, 11:13
Забыл уточнить - меня интересует управление памятью в Linux.
Я замечал, что количество памяти, занимаемой моей программой только увеличивается. (до определённого момента, как я понимаю - это не утечки, а увеличение происходит после использования ранее не использованных функций программы. Как все функции отработали, использование памяти почти не увеличивается).  Как я понимаю, занятая память расходуется на стек. Потом, после отработки функций, она помечается, как неиспользуемая, но в систему не возвращается (или всё же должна возвращаться?).  Конечно, я сейчас буду забросан овощами, но для мониторинга использую free -m. Ещё менеджер процессов из xfce. 
Насколько это всё вышеописанное корректно?


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: kibsoft от Январь 29, 2010, 11:22
Проверял в винде с помощью менеджера процессов, тоже память только увеличивалась, но деструкторы объектов вызывались, т.е. объекты уничтожались..вывод - менеджеры процессов показывают совсем не то..возможно память остается зарезервированной у приложения для следующих вызовов..


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Январь 29, 2010, 11:52
вывод - менеджеры процессов показывают совсем не то..возможно память остается зарезервированной у приложения для следующих вызовов..
Точно.
Все эти менеджеры и утилиты, показывают сколько все памяти операционная система отдала процессу.
Т.е. программа аллоцирует несколько мегабайт, система предоставляет ей эту память, программа освобождает этот блок, если системе не нужно, она может не забрать эту память у процесса или забрать только часть. Но для процесса эта память свободна и может быть распределена для других блоков.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Unnamed_Hero от Январь 29, 2010, 12:05
Цитировать
Т.е. программа аллоцирует несколько мегабайт, система предоставляет ей эту память, программа освобождает этот блок, если системе не нужно, она может не забрать эту память у процесса или забрать только часть. Но для процесса эта память свободна и может быть распределена для других блоков.

Но освобождённые (допустим) пол-мегабайта из ранее зарезервированного мегабайта будут доступны только этой программе, и не доступны другим процессам, так? Если программе внезапно понадобилось 10 (100, >9000) мегабайт для расчётов, то память ей выделится, расчёты пройдут, память больше не нужна, а что  потом будет с этой памятью?


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Январь 29, 2010, 12:28
Но освобождённые (допустим) пол-мегабайта из ранее зарезервированного мегабайта будут доступны только этой программе, и не доступны другим процессам, так? Если программе внезапно понадобилось 10 (100, >9000) мегабайт для расчётов, то память ей выделится, расчёты пройдут, память больше не нужна, а что  потом будет с этой памятью?
Нужно разделять физическую память и виртуальную.
Например, на машине (x86) есть 1Gb физической памяти, а каждый процесс может получить 2-3 Gb (в зависимости от OS) виртуальной памяти.
Т.е. OS на уровне страниц предоставляет необходимые блоки физической памяти процессу, и так же легко их забирает, если к участку виртуальной памяти долгое время никто не обращался, для других процессов.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Unnamed_Hero от Январь 29, 2010, 12:36
А не проще ли, допустим, некие объёмные по памяти вычисления выносить в отдельный тред (применительно к qt), дабы после его отработки память сразу же вернулась в систему?


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Январь 29, 2010, 12:48
Все треды выполняются в пространстве процесса его породившего, т.е. в одном адресном пространстве.
Тебе не нужно заботиться о том, что бы память вернулась системе, если ей понадобиться она все заберет сама.  :)
Менеджер памяти распределяет виртуальную память, физические страницы будут распределяться ядром.
Например в linux, если процесс будет захватывать большие блоки памяти, они будут распределяться с конца кучи, если маленькие сначала. При возможности, свободные блоки будут объединятся, для того что бы можно было выделить как можно больший непрерывный блок.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Akaiten от Январь 29, 2010, 14:12
Сишный менеджер памяти обычно запрашивает у системы больший кусок памяти, чем требуется, и затем раздаёт его по кусочкам при вызовах malloc() или new. После вызова free() или delete память с точки зрения программы освобождена, но сишный менеджер памяти может не отдать её системе. Обычно он отдаёт память системе, когда образуется непрерывный блок "свободной" памяти достаточного размера. Всё это сделано для увеличения производительности, поскольку функции выделения/освобождения памяти довольно трудоёмки.

Если пишешь под linux посмотри функцию mallopt().
Можно написать (или найти) свой менеджер памяти.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Unnamed_Hero от Январь 29, 2010, 14:21
Все треды выполняются в пространстве процесса его породившего, т.е. в одном адресном пространстве.
Тебе не нужно заботиться о том, что бы память вернулась системе, если ей понадобиться она все заберет сама.  :)

В ассистанте прочитал:
Цитировать
Each thread gets its own stack from the operating system. The operating system also determines the default size of the stack. You can use setStackSize() to set a custom stack size.

На основе этого я подумал, что тред получает свою область памяти, не зависящую от родительского процесса; хотя, ранее там же написано, что
Цитировать
A QThread represents a separate thread of control within the program; it shares data with all the other threads within the process but executes independently in the way that a separate program does on a multitasking operating system.
значит, всё же у него свой стек, но внутри стека основного процесса?


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Akaiten от Январь 29, 2010, 15:04
значит, всё же у него свой стек, но внутри стека основного процесса?

ты вообще читаешь, что тебе отвечают???


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Igors от Январь 31, 2010, 02:11
Ну вот, запутали человека, а потом еще и накричали на него  :)

1) У каждой thread (нитки) свой стек, выделяется OS'ом. Как он его выделяет - его личное дело, знание этих подробностей ничего практически не дает.

2) Наукообразные выражения типа "Выделение памяти на стеке" (так же как и "стековая память быстрее") - сбивают с толку, можно подумать что это что-то типа new. В действительности все "выделение" сводится к одной команде, а "освобождение" - к другой

Код:
sub  esp, 8    // "выделить" 8 байт на стеке
...
add  esp, 8    // "освободить" их
Пусть регистр esp указывал на какой-то адрес, напр 100 (условно конечно, реальный адрес смотрится типа 0xABD00F00). Вычли из esp 8, теперь esp = 92. Значит, в байтах [92..99]  можно что-то хранить. Если еще потребуется - опять вычтем из esp (стек растет в сторону уменьшения адресов). Ясно, до тех пор пока не исчерпаем стек. Когда мы добавили к esp - используемые байты никуда не делись - просто их может теперь использовать следующий "вычитающий".

Раньше была классная программа Turbo Debugger - там это все было видно живьем.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 05, 2010, 23:19
А как нибудь можно вычислить необходимы размер стека...а то у меня прога при разных значения то падает (segmentation fault) -указывал 1-2Мб то пишет ошбку - Qthread::start: Thread stack size error:....это все на линуксе


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Март 05, 2010, 23:31
Ты что на стеке потока большие буферы размещаешь?
Или рекурсию используешь?
По умолчанию размер стека, как бы совсем не мал для обычной работы.

$ ulimit -s
10240

Это в Кб.



Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 05, 2010, 23:37
внутри функции run цикл стоит в котором идет работа с сокетом...щас попробую до 2ух мегабайт увеличить в limits.conf


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Март 05, 2010, 23:41
внутри функции run цикл стоит в котором идет работа с сокетом...щас попробую до 2ух мегабайт увеличить в limits.conf
Размер стека можно задавать каждому потоку:
void QThread::setStackSize ( uint stackSize )

IMHO, что то у тебя в run не так...


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 05, 2010, 23:51
да я уже тоже думал так....но 400 потоков запускаюся а 500 нет...ограничения на открытые файлы снял....вот сижу и тыкась с размерами....по умолчанию в Ubuntu 8192 кб(слишком много на 400 потоков)...а еще вопрос setSocketSize в чем указывается размер б\Кб????


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: BRE от Март 05, 2010, 23:53
да я уже тоже думал так....но 400 потоков запускаюся а 500 нет...ограничения на открытые файлы снял....вот сижу и тыкась с размерами....по умолчанию в Ubuntu 8192 кб(слишком много на 400 потоков)...а еще вопрос setSocketSize в чем указывается размер б\Кб????
Цитировать
Sets the maximum stack size for the thread to stackSize. If stackSize is greater than zero, the maximum stack size is set to stackSize bytes, otherwise the maximum stack size is automatically determined by the operating system.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 05, 2010, 23:55
спасибо...самое итересно дважды до этого читал и не заметил...спасибо еще раз...буду дальше мучаться с запуском!


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: ритт от Март 06, 2010, 02:28
> 400 потоков запускаюся а 500 нет

у вас там кластер, что ли? похоже, что нет, раз какие-то проблемы с выделением памяти...
суперкомпьютер? похоже, что нет, раз какие-то проблемы с выделением памяти...
резолюция: нахера?! :)


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 06, 2010, 11:10
задача такая!!!! я согласен что звучить старнно, но что есть то есть....


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: Rcus от Март 06, 2010, 19:47
Прикладная задача врядли в явном виде требует создания такого количества конкурентных потоков выполнения (если только задача не заключается в тестировании планировщика). Вполне может быть что вы не рассмотрели другие варианты решения изначальной проблемы (или не знали об их существовании), а потому считаете необходимость создания большого числа потоков частью проблемы, а не решения.


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: lit-uriy от Март 06, 2010, 20:14
может задача учебная


Название: Re: Как Qt работает с памятью и вообще про память
Отправлено: garryHotDog от Март 07, 2010, 14:35
так и сделал...избавился от потоков - сокеты работают в асинхронном режиме....для себя сделал вывод что с если потоков много жди беды