Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Менеджер памяти.

6.0K
03 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Дарофф!
Пишу по-тихоньку оську, дошел до распределения памяти, как это в принципе реализуется?
Я просто вообще без понятия - хочу сделать таблицу идентификаторов владельца для каждой страницы, а уже детально каждую выделенную страницу расписывать в описывающей процесс структуре.
В этом и проблема-каким образом лучше и как помечать занятые места в странице?
261
05 июля 2007 года
ahilles
1.5K / / 03.11.2005
что-то неопнятно
Цитата: artyom-tyanutov

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


у тебя все процессы находятся в одном адресном пространстве и как?
мне кажется лучше чтобы для каждого процесса своя память.

Цитата: artyom-tyanutov

.... а уже детально каждую выделенную страницу расписывать в описывающей процесс структуре.


для каждой физической страницы или виртуальной? а зачем детально?

Цитата: artyom-tyanutov

В этом и проблема-каким образом лучше и как помечать занятые места в странице?


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

конкретнее вопрос надо задавать....

6.0K
05 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Каждый процесс в своем адресном пространстве.
Просто целыми страницами каждый раз выделять это больно расточительно, поэтому надо как-то помешать сколько чего выделено в какой странице.
Только как лучше это сделать-разбить страницу на блоки или писать размер выделенного?
261
06 июля 2007 года
ahilles
1.5K / / 03.11.2005
ну это просто глупо! придумать как помечать занятые места на странице - вот что расточительно. Это будет настолько сложно (я думаю что невозможно) и тратить на это такты процессора и это просто не "окупится". Во всем известной Windows выделяемая память всегда кратна 4 КБ и всё вроде нормально (даже если ты выделишь 5 байтов памяти всё равно выделится 4 КБ)........
P.S. и тем более на всех нынешних более менее современных машинах стоит как минимум 256 МБ оперативки
6.0K
06 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Всего то?
Я думал менеджер памяти будет куда геморойнее!
А на счет того что ведь функции free передается просто адрес, то так как надо отмечать диапазон, чтобы корректно освободить их все, то я думаю вместо битовой карты использовать структуру с ролями описывающими владельца для каждой страницы и конец выделенного блока.
Как это делается на самом деле?
6.0K
10 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Но в мастдае и линухе выделенная память не кратна 0х1000 как было упомянуто-она кратна 16 байтам!
1.9K
10 июля 2007 года
disasm
232 / / 06.02.2006
Смотря чем выделенная.
В ОС память выделяется так: если надо 16 байт, вэделяем страницу, а потом в специальной таблице пишем что в этой странице много яцеек по 16 байт, и когда следующий раз понядобится еще 16 байт, система заберет их уже из этой таблицы. В реале в линуксе выделится не 16 байт каздый раз, поскольку перед каждым блоком, который отдается программе, есть блок, в котором указан указатель на следующий пустой, если пустых нет, то он равен нулю.
В этом случае система при отстутствии пустых ячеек выделит еще одну страницу и указатель на нее запишет вместо этого нуля.
261
10 июля 2007 года
ahilles
1.5K / / 03.11.2005
но ведь всё равно реально выделится страница виртуальной и физической памяти. Даже если ты выделишь память 16 байт например по адресу 0х00010000 в режиме чтения и записи, то всё равно можно будет обратиться по адресу 0х00010025 с операцией записи (там просто могут находиться данные которые используют другие потоки).
to artyom-tyanutov:
выделять память с точностью в 1 байт это глупо
1.9K
10 июля 2007 года
disasm
232 / / 06.02.2006
Да я и не отрицаю..
Выделить память по конкретному адресу можно только страницами. Если выделать блоками, то перед блоком обычно идет 8 байт (реально надо 6, но это для выравнивания 8)
350
11 июля 2007 года
cheburator
589 / / 01.06.2006
Управление физическими и виртуальными страницами - низкий уровень.
Выделение памяти приложению - высокий уровень.
Это разные уровни.
6.0K
11 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
А тогда в memory map'е хранить битовую карту или id владельцев страниц?
При последнем удобнее освобождать память после завершения процесса, но первое компактнее и узнать где чья страничка сложнее.
1.9K
11 июля 2007 года
disasm
232 / / 06.02.2006
А зачем собственно хранить владельца??
Можно поступить так: все, что выше какого-то адреса - владения ядра, все что ниже - владения пользователя. Это касается виртуальной памяти. При завершении процесса просто пройтись по PDE+PTE, которые относятся к пользователю и поудалять страницы виртуальной памяти. При удалении страниц виртуальной памяти сразу освобождать соответствующую им физическую память.
В этом случае можно просто ограничиться одной таблицей для физической памяти, в которой хранить занятость страницы и размер блока. Для занятых блоков во всех элементах прописывать "занято" (0x80000000), а для первого это значение еще OR`ить с размером блока. То же самое для свободных блоков, только без флага "занято". Для одного Гб физической памяти такая страница занимает 1 Мб, не так уж и много..
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
для совместно используемых страниц такой вид карты не прокатит .
1.9K
11 июля 2007 года
disasm
232 / / 06.02.2006
Shared-страниц? В этом случае можно в дескрипторах страницы указать что она Shared, и создать счетчик исползования страницы, при освобождении из одного процесса уменьшать его на 1, когда он станет равным нулю освободить физическую память под эту страницу.
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
а не проще сразу карту памяти со счётчиком делать ?
0- страница свободна ;
х<max - кол-во ниток использующих страницу ;
x>=max - специальные значения ;
старший бит - флаг разрешения перемещения страницы (чтоб не свопить ядро и драва :) ) ;
1.9K
11 июля 2007 года
disasm
232 / / 06.02.2006
В этом случае:
+ в таблице прописано количество тредов
- намного больше времени на выделение блоков физической памяти больше одной страницы
? и зачем флаг разрешения перемещения страницы ? Можно просто не свопать все верхние страницы памяти
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
виртуально страницы выделять сразу все 4 гига (за некоторым вычетом) , а физические выделять по мере необходимости .
что значит верхние - нижние ?
1.9K
11 июля 2007 года
disasm
232 / / 06.02.2006
Выделять сразу 4 гига неэффективно, т.к. для этого уйдет 4 мб на прогу. Это пренебрегая расшареностью памяти ядра.
Под верхней памятью я имелл ввиду верхние адреса, те что не принадлежат пользовательским сегментам кода и данных.
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
каталог таблиц + таблица страниц (больше трех-четырех ненадо , остальные по мере необходимости создаются и заполняются) = (4|5)*4=16|20 кб .
зачем ядро в пользовательском пространстве вообще ?
1.9K
11 июля 2007 года
disasm
232 / / 06.02.2006
Ядро не в пользовательском режиме, но для обеих режимов таблица PDE одна и та же. А значит в каждом процессе должна быть прошарена память ядра. Подсистема управления свопом не должна обращать внимания на память ядра, а свопать только память самой проги. Хотя даже в NT, например, это не так, но для своей ОС вполне подойдет такой принцип.

Пора прекращать холивар, в принципе обсудили несколько вариантов нормальной организации памяти, и хватит.
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
если таблицы для каждого процесса разные , то это не обязательно .нечего делать ядру в адресном пространстве пользовательского процесса .
6.0K
11 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
А монтировать страницы лучше по последнему не занятому адресу или куда попало, тоесть по физическому?
252
11 июля 2007 года
koderAlex
1.4K / / 07.09.2005
при страничной адресации и правильно сделаной карте памяти нет никакого дела до физического размещения .
6.0K
12 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Да я в курсе, имел в виду пусть какая-то прога запросила страницу памяти, в карте найду ее физический адрес, так вот ее монтировать по физическому адресу или по первому "пустому" виртуальному?
252
12 июля 2007 года
koderAlex
1.4K / / 07.09.2005
когда приложения пытается обратится к несуществующей странице происходит исключетие PF - ошибка страницы . в обработчик передаётся линейный адрес . по этому адресу определяеш место в таблицах куда и монтируеш страничку .
6.0K
12 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
1) А сколько надо оставить места для числа процессов, использующих одну страницу?
Байта хватит?
2) Известно что маллок перед выделенным блоком помещает 4 байта с указателем на следующий блок.
А как тогда помечать свободно/занято ведь указатель нужен один фиг?
Попробую предположить что можно это делать 7-м от 0 битом ведь например в мастдае 2 Гб максимум на прогу поэтому последний бит свободен.
Так?
1.9K
12 июля 2007 года
disasm
232 / / 06.02.2006
2)
А зачем помечать?? Есть массив(таблица), каждый его элемент - указатель на свободный блок заданного размера. В этом блоке первые 4 байта - указатель на следующий свободный блок, и.т.д в конце - ноль. Каждый элемент массива отвечает за список блоков определенной длины. Т.е. элементы массива будут для блоков длины 16, 32, 64, 128, 256, 512, 1024, 2048 байт. Для длин 4096+ память выделяется страницами в обход этой таблицы.
Занятые блоки не связаны в список, и у них эти 4 байта обозначают размер. Т.е. когда нужно удалить блок смотрим размер этого блока, потом вместо него записываем указатель, который хранится в таблице, а в таблицу вместо него ставим указатель на только что освободившийся блок.
Когда нужно выделить блок, берем тот блок, адрес которого сейчас в таблице, а вместо этого адреса в таблицу пишем значение первых четырех байт этого блока. А в первые четыре байта этого блока пишем его размер (16,32, ..., а не то, сколько программа попросила)
6.0K
15 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
И где держать эту таблицу?
А если все блоки объединить в список а занятые помечать 7-ым битом как я сказал?
Так и расколоть блок без проблем если что можно, так на много проще, не тратится место под таблицу да и тормознее ли он вообще(проц'у я думаю пофиг по какому адресу mov'ать)?
1.9K
15 июля 2007 года
disasm
232 / / 06.02.2006
Таблица из 8-ми DWORD-ов всего... Я бы поместил ее в структуру, описывающую процесс. Еще надо создать отдельную таблицу для памяти ядра, общую для всех процессов.
В твоем методе один минус: когда надо будет удалить память, ты не будешь знать ее размера. Кроме того если у тебя будет одна цепочка для занятых, и одна для свободных, то очень много времени займет поиск свободного блока заданного размера... Очень неэффективно.
Тот способ, что я описал работает в этом плане намного эффективней.

Кроме того 32 байта на процесс (размер таблицы) не сильно нагрузит память ))
6.0K
15 июля 2007 года
artyom-tyanutov
107 / / 10.07.2006
Чет я не понял-ты сказал что в таблице содержатся указатели на свободные блоки, тогда почему их только 8?
И я предлагал одну цепочку и для занятых, и для свободных блоков, поэтому размер я знать буду.
6.0K
02 августа 2007 года
artyom-tyanutov
107 / / 10.07.2006
Спасибо всем, вроде написал что-то работающее
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог