![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Christoph |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 667 Регистрация: 23.1.2008 Где: Харьков Репутация: 1 Всего: 11 |
Хотел бы разобраться с менеджером памяти в делфи
http://gunsmoker.blogspot.com/2009/01/blog-post.html - читал вот эту статью Появилось немного вопросов, я понмню что 1 тема - 1 вопрос, но эти вопросы относятся к одной теме "Зачем вообще нужен менеджер памяти? Почему нельзя использовать функции управления памятью операционной системы? Потому что это будет утечка абстракции. Системный способ выделить память - это функция VirtualAlloc. Проблема в том, что эта функция слишком близко сидит к железу: она выделяет память только страницами. Обычно размер страницы равен 4 Кб. Это аналогично тому, как в файловой системе файлы адресуются только кластерами (размер кластера обычно варьируется от 4 Кб до 64 Кб). Иными словами, нельзя выделить памяти меньше, чем 1 страница. Т.е. если вы создаёте 100 объектов по, скажем, 12 байт (очень простые объекты, вы их наследовали от TObject), то вместо двух килобайт (12 * 100 = 1.2 Кб) вы занимаете уже 50 Кб (12 * 4 = 48 Кб) - в 25 раз больше. А строки? В типичной программе используется несметное количество строк, размер которых обычно не превышает одного предложения (все эти Caption, Hint, MessageBox и т.п.). Использовали бы вы VirtualAlloc - вы бы очень быстро исчерпали свободную память (а ведь есть ещё проблема фрагментации памяти)." VirtualAlloc - выделяет память только страницам,а я читал что память может быть разбита на страница а может быть разбита на сегменты, от чего это зависит? Почему получается что под 100 объектов надо 50Кб? " Вот рассмотрим пример, когда программа вызывает функцию из DLL, а та возвращает строку String. Без использования общего менеджера памяти строку String выделяет менеджер DLL библиотеки, поэтому информация о ней лежит на левом рисунке по красным линиям. После того, как в главном приложении вы обработали эту строку, она будет удалена автоматически, как только станет вам не нужна (ну или вы сами явно её не обнулите). Но освобождать-то строку будет уже код программы. Это значит, что он попытается найти запись о строке по синим стрелочкам (левый рисунок), но она-то лежит в одном из блоков, на который указывают красные стрелочки. Упс-с... " Получается что менеджер памяти exe хочет удалить строчку выделенную менджером DLL? Почему не делает этого менджер DLL, это получается DLL выделил кусочик памяти, а пусть удаляет другой? Это сообщение отредактировал(а) Christoph - 23.2.2009, 20:18 -------------------- ![]() |
|||
|
||||
| CodeMonkey |
|
||||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 38 Всего: 89 |
В Windows и большинстве современных систем используется плоская страничная модель памяти. Сегментная модель памяти использовалась во времена DOS, потому что в 16-ти разрядный адрес можно записать максимум число 65535. Ну никак даже мегабайт не получается. Поэтому и использовали сегментную модель. Два адреса (сегмент + смещение) по 16-бит - в итоге адресовать можем много. Сейчас смысла делать так уже никакого. Плоская модель работает эффективно и она проще для понимания.
Да.
Вы из DLL вернули String:
В exe вы её используете. Как только закончили использовать - её удаляете. Вы не знаете ничего про менеджер памяти в DLL, поэтому всё, что вы можете сделать со строкой, - это передать её своему менеджеру памяти:
Добавлено через 3 минуты и 3 секунды Ошибочка там. Должно стоять 100 * 4 = 400 Кб. Не то число поменял в формуле. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||||||||
|
|||||||||||
| Christoph |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 667 Регистрация: 23.1.2008 Где: Харьков Репутация: 1 Всего: 11 |
На эти вопросы я получил ответ, читаю дальше
"Как это решает менеджер памяти программы? Это легко понять, исходя из принципа его работы. Он выделяет себе несколько рабочих кусков памяти в помощью VirtualAlloc (а также выделяет их в дальнейшем по мере необходимости). Блоки эти имеют достаточный размер и всегда кратны размерам страницы. Когда программа просит его выделить память, он "выделяет" её в своих блоках. "Выделяет" не зря взято в кавычки. Ведь на самом деле он просто возвращает указатель на какую-то часть одного из своих рабочих блоков памяти - ту, которую он считает свободной по своим записям. " VirtualAlloc выделяет память в несколько страниц,и затем их объеденяет в один кусок памяти? и затем может идти запись данных компактно? Верно я понял? 7 страно как то VirtualAlloc работает и я так понял -------------------- ![]() |
|||
|
||||
| CodeMonkey |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 38 Всего: 89 |
Если вы выделяете блок в несколько страниц, то объединять там нечего - он и так непрерывен. Если вы выделяете два блока подряд (не важно, в одну или несколько страниц размером) - они могут располагаться непрерывно друг относительно друга, но это вовсе не обязательно. При чём здесь VirtualAlloc вообще? Он не имеет никакого отношения к тому, как вы собираетесь использовать память, которую у него попросили.
Вот чтобы не оставлять свободное место и нужен менеджер памяти. Как раз он и следит, где чего у нас выделено, а где ещё свободно. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||
|
|||||
| Christoph |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 667 Регистрация: 23.1.2008 Где: Харьков Репутация: 1 Всего: 11 |
Спасибо разобрал, Лови плюсик
-------------------- ![]() |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |