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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как Qt работает с памятью и вообще про память  (Прочитано 24845 раз)
Unnamed_Hero
Гость
« : Январь 28, 2010, 15:31 »

Посоветуйте, что можно почитать про организацию работы с памятью, её эффективного использования, как Qt работает с памятью.
Есть несколько вопросов-утверждений. Насколько они верны? Что можно почитать, чтобы не возникали подобные вопросы?

-У программы есть стек, туда пишутся все локальные переменные функций. запустилась функция - в стеке выделились необходимые блоки памяти для хранения переменных. функция отработала - память помечена как свободная. Туда могут быть помещены новый данные.
-Во время работы программы он может только расти, но не уменьшаться.
-Память из стека возвращается в систему только по закрытию программы.
-Qt'шные треды используют свой стек (если верить дизайнеру) - значит ли, что после отработки треда память, выделенная для стека треда, возвратиться в систему, или всё же стек для треда создаётся внутри стека программы?
Записан
Akaiten
Гость
« Ответ #1 : Январь 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
  • Средства для работы с памятью языка программирования. Первое что нагуглил Улыбающийся
« Последнее редактирование: Январь 28, 2010, 17:11 от Akaiten » Записан
Amigo_sa
Гость
« Ответ #2 : Январь 28, 2010, 17:17 »

Про организацию работы с памятью можно очень много всего написать. Статей и учебников куча. Qt - обычная библиотека, она работает с памятью точно так же как и любая C++ программа.

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

-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
-не верно.
-Память для статических объектов освобождается после завершения области видимости, для динамической - вызовом оператора delete.
-В тредах ессно свой стек, и свой цикл обработки сообщений.
Записан
BRE
Гость
« Ответ #3 : Январь 28, 2010, 17:40 »

-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
Непонимающий Стек один на весь процесс. Какой свой стек для каждой функции?

-В тредах ессно свой стек, и свой цикл обработки сообщений.
Только если его запустить, а можно и не запускать...
Записан
Amigo_sa
Гость
« Ответ #4 : Январь 28, 2010, 17:59 »

-У каждой функции есть собственный стек, который очищается после возврата управления из функции.
Непонимающий Стек один на весь процесс. Какой свой стек для каждой функции?
Да конечно, извините, я не верно сформулировал. Я имел в виду, что при вызове функции в стек помещается адрес вызова, параметры и дальше он разворачивается ничего не зная о том, кто его вызвал. А при завершении, стек очищается.
Записан
Unnamed_Hero
Гость
« Ответ #5 : Январь 29, 2010, 11:13 »

Забыл уточнить - меня интересует управление памятью в Linux.
Я замечал, что количество памяти, занимаемой моей программой только увеличивается. (до определённого момента, как я понимаю - это не утечки, а увеличение происходит после использования ранее не использованных функций программы. Как все функции отработали, использование памяти почти не увеличивается).  Как я понимаю, занятая память расходуется на стек. Потом, после отработки функций, она помечается, как неиспользуемая, но в систему не возвращается (или всё же должна возвращаться?).  Конечно, я сейчас буду забросан овощами, но для мониторинга использую free -m. Ещё менеджер процессов из xfce. 
Насколько это всё вышеописанное корректно?
Записан
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #6 : Январь 29, 2010, 11:22 »

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

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
BRE
Гость
« Ответ #7 : Январь 29, 2010, 11:52 »

вывод - менеджеры процессов показывают совсем не то..возможно память остается зарезервированной у приложения для следующих вызовов..
Точно.
Все эти менеджеры и утилиты, показывают сколько все памяти операционная система отдала процессу.
Т.е. программа аллоцирует несколько мегабайт, система предоставляет ей эту память, программа освобождает этот блок, если системе не нужно, она может не забрать эту память у процесса или забрать только часть. Но для процесса эта память свободна и может быть распределена для других блоков.
Записан
Unnamed_Hero
Гость
« Ответ #8 : Январь 29, 2010, 12:05 »

Цитировать
Т.е. программа аллоцирует несколько мегабайт, система предоставляет ей эту память, программа освобождает этот блок, если системе не нужно, она может не забрать эту память у процесса или забрать только часть. Но для процесса эта память свободна и может быть распределена для других блоков.

Но освобождённые (допустим) пол-мегабайта из ранее зарезервированного мегабайта будут доступны только этой программе, и не доступны другим процессам, так? Если программе внезапно понадобилось 10 (100, >9000) мегабайт для расчётов, то память ей выделится, расчёты пройдут, память больше не нужна, а что  потом будет с этой памятью?
Записан
BRE
Гость
« Ответ #9 : Январь 29, 2010, 12:28 »

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

А не проще ли, допустим, некие объёмные по памяти вычисления выносить в отдельный тред (применительно к qt), дабы после его отработки память сразу же вернулась в систему?
Записан
BRE
Гость
« Ответ #11 : Январь 29, 2010, 12:48 »

Все треды выполняются в пространстве процесса его породившего, т.е. в одном адресном пространстве.
Тебе не нужно заботиться о том, что бы память вернулась системе, если ей понадобиться она все заберет сама.  Улыбающийся
Менеджер памяти распределяет виртуальную память, физические страницы будут распределяться ядром.
Например в linux, если процесс будет захватывать большие блоки памяти, они будут распределяться с конца кучи, если маленькие сначала. При возможности, свободные блоки будут объединятся, для того что бы можно было выделить как можно больший непрерывный блок.
« Последнее редактирование: Январь 29, 2010, 12:57 от BRE » Записан
Akaiten
Гость
« Ответ #12 : Январь 29, 2010, 14:12 »

Сишный менеджер памяти обычно запрашивает у системы больший кусок памяти, чем требуется, и затем раздаёт его по кусочкам при вызовах malloc() или new. После вызова free() или delete память с точки зрения программы освобождена, но сишный менеджер памяти может не отдать её системе. Обычно он отдаёт память системе, когда образуется непрерывный блок "свободной" памяти достаточного размера. Всё это сделано для увеличения производительности, поскольку функции выделения/освобождения памяти довольно трудоёмки.

Если пишешь под linux посмотри функцию mallopt().
Можно написать (или найти) свой менеджер памяти.
Записан
Unnamed_Hero
Гость
« Ответ #13 : Январь 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.
значит, всё же у него свой стек, но внутри стека основного процесса?
Записан
Akaiten
Гость
« Ответ #14 : Январь 29, 2010, 15:04 »

значит, всё же у него свой стек, но внутри стека основного процесса?

ты вообще читаешь, что тебе отвечают???
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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