Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Менеджер памяти в Delphi 
V
    Опции темы
Christoph
Дата 23.2.2009, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 1
Всего: 11



Хотел бы разобраться с менеджером памяти в делфи 
http://gunsmoker.blogspot.com/2009/01/blog-post.html - читал вот эту статью
Появилось немного вопросов, я понмню что 1 тема - 1 вопрос, но эти вопросы относятся к одной теме  smile 


"Зачем вообще нужен менеджер памяти? Почему нельзя использовать функции управления памятью операционной системы?
Потому что это будет утечка абстракции. Системный способ выделить память - это функция 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


--------------------
user posted image
PM MAIL ICQ   Вверх
CodeMonkey
Дата 23.2.2009, 21:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Christoph @  23.2.2009,  20:17 Найти цитируемый пост)
а я читал что память может быть разбита на страница а может быть разбита на сегменты, от чего это зависит?

В Windows и большинстве современных систем используется плоская страничная модель памяти. Сегментная модель памяти использовалась во времена DOS, потому что в 16-ти разрядный адрес можно записать максимум число 65535. Ну никак даже мегабайт не получается. Поэтому и использовали сегментную модель. Два адреса (сегмент + смещение) по 16-бит - в итоге адресовать можем много. Сейчас смысла делать так уже никакого. Плоская модель работает эффективно и она проще для понимания.

Цитата(Christoph @  23.2.2009,  20:17 Найти цитируемый пост)
Получается что менеджер памяти exe хочет удалить строчку выделенную менджером DLL?

Да.

Цитата(Christoph @  23.2.2009,  20:17 Найти цитируемый пост)
Почему не делает этого менджер DLL, это получается DLL выделил кусочик памяти, а пусть удаляет другой?

Вы из DLL вернули String:

Код
function gg: String;
begin
  Result := 'dfgfdg' + IntToStr(SomeOtherFunc); // << менеджер памяти DLL выделять память под строку в Result
end;

exports
  gg;


В exe вы её используете. Как только закончили использовать - её удаляете. Вы не знаете ничего про менеджер памяти в DLL, поэтому всё, что вы можете сделать со строкой, - это передать её своему менеджеру памяти:
Код
function gg: String; external 'test.dll';
...
var
  S: String;
begin
  S := gg;
  ShowMessage(S);
end; // << здесь строка S будет освобождена. Запрос на освобождение получит менеджер памяти в exe, поскольку сейчас мы находимся в exe


Добавлено через 3 минуты и 3 секунды
Цитата(Christoph @  23.2.2009,  20:17 Найти цитируемый пост)
Почему получается что под 100 объектов надо 50Кб?

Ошибочка там. Должно стоять 100 * 4 = 400 Кб. Не то число поменял в формуле.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Christoph
Дата 23.2.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 1
Всего: 11



На эти вопросы я получил ответ, читаю дальше 

"Как это решает менеджер памяти программы? Это легко понять, исходя из принципа его работы. Он выделяет себе несколько рабочих кусков памяти в помощью VirtualAlloc (а также выделяет их в дальнейшем по мере необходимости). Блоки эти имеют достаточный размер и всегда кратны размерам страницы. Когда программа просит его выделить память, он "выделяет" её в своих блоках. "Выделяет" не зря взято в кавычки. Ведь на самом деле он просто возвращает указатель на какую-то часть одного из своих рабочих блоков памяти - ту, которую он считает свободной по своим записям. "

VirtualAlloc выделяет память в несколько страниц,и затем их объеденяет в один кусок памяти? и затем может идти запись данных компактно? Верно я понял?
7

Цитата(Christoph @  23.2.2009,  20:17 Найти цитируемый пост)
Обычно размер страницы равен 4 Кб. Это аналогично тому, как в файловой системе файлы адресуются только кластерами (размер кластера обычно варьируется от 4 Кб до 64 Кб). Иными словами, нельзя выделить памяти меньше, чем 1 страница. Т.е. если вы создаёте 100 объектов по, скажем, 12 байт (очень простые объекты, вы их наследовали от TObject), то вместо двух килобайт (12 * 100 = 1.2 Кб) вы занимаете уже 50 Кб (12 * 4 = 48 Кб) - в 25 раз больше.

страно как то VirtualAlloc работает smile чтоб записывать новые данные надо выделять новую страницу, зачем же оставлять свободное место? 
и я так понял smile несколько страниц объдиняют в одну большую страницу?


--------------------
user posted image
PM MAIL ICQ   Вверх
CodeMonkey
Дата 24.2.2009, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Christoph @  23.2.2009,  23:13 Найти цитируемый пост)
VirtualAlloc выделяет память в несколько страниц,и затем их объеденяет в один кусок памяти?

Если вы выделяете блок в несколько страниц, то объединять там нечего - он и так непрерывен. Если вы выделяете два блока подряд (не важно, в одну или несколько страниц размером) - они могут располагаться непрерывно друг относительно друга, но это вовсе не обязательно.

Цитата(Christoph @  23.2.2009,  23:13 Найти цитируемый пост)
страно как то VirtualAlloc работает

При чём здесь VirtualAlloc вообще? Он не имеет никакого отношения к тому, как вы собираетесь использовать память, которую у него попросили.

Цитата(Christoph @  23.2.2009,  23:13 Найти цитируемый пост)
чтоб записывать новые данные надо выделять новую страницу, зачем же оставлять свободное место?

Вот чтобы не оставлять свободное место и нужен менеджер памяти. Как раз он и следит, где чего у нас выделено, а где ещё свободно.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Christoph
Дата 24.2.2009, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 1
Всего: 11



Спасибо разобрал, Лови плюсик smile 


--------------------
user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0459 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.