PDA

Просмотр полной версии : Сборка мусора



captain cobalt
29.03.2005, 16:15
Сборка мусора - это способ автоматического управления памятью, применяемый в большинстве функциональных языков программирования и в некоторых императивных языках. В том числе в технологиях Java и .NET от известных транснациональных корпораций.

Автоматическое управление памятью с помощью сборки мусора налагает некоторые ограничения на программы (например, требование ссылочной прозрачности всех структур данных).
Однако радикально поднимает удобство программирования.

Какие будут мнения насчёт обоснованности применения сборщиков мусора в средах исполнения на Speccy?

GriV
29.03.2005, 16:17
Я например не знаю...

captain cobalt
29.03.2005, 16:33
Сборка мусора - это способ автоматического управления памятью, при котором программы не освобождают память явно. Вместо этого при исчерпании памяти запускается сборщик мусора, который определяет, какая память больше не нужна, и утилизирует её.

elf/2
29.03.2005, 16:41
какая память больше не нужна
как ты предполагаешь определять какая память больше не нужна?

для сборки мусора необходимо определить когда та или иная переменная/объект вышла/ел из области видимости. сие не представляется возможным по причине отсутсвия понятия переменной/объекта в используемых языках программировая (асм)

GriV
29.03.2005, 16:49
как собирается автор внедрять методы языков высокого уровня на ZX, а так же чем не устраивают стандартные способы разделения памяти?

random
29.03.2005, 16:57
Не стоит смеяться. Это очень полезный вопрос. В связи с перекладыванием функций выделения памяти на ось, туда же падает освобождение памяти. Во всяком случае, когда программа самоликвидировалась, необходимо освободить всю принадлежащую ей память.

captain cobalt
29.03.2005, 17:01
как ты предполагаешь определять какая память больше не нужна?

для сборки мусора необходимо определить когда та или иная переменная/объект вышла/ел из области видимости. сие не представляется возможным по причине отсутсвия понятия переменной/объекта в используемых языках программировая (асм) Динамическое управление памятью заключается в том, что имеется большая область памяти, называемая "куча". Программы могут динамически запрашивать память нужного им размера, при этом им выдаётся указатель на выделенную в куче память.

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

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

Ассемблер - не очень удобный язык для программирования совместно со сборкой мусора. Следует использовать язык более высокого уровня.

GriV
29.03.2005, 17:08
Динамическое управление памятью заключается в том, что имеется большая область памяти, называемая "куча". Программы могут динамически запрашивать память нужного им размера, при этом им выдаётся указатель на выделенную в куче память.

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

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

Ассемблер - не очень удобный язык для программирования совместно со сборкой мусора. Следует использовать язык более высокого уровня.

Замечательно! И где такой ЯВУ взять? И потом, кто сказал что система не управляет таким образом памятью? Да, TRDOS не управляет так, да BASIC не управляет так, но они то и системами могут быть с трудом названы... А потом, как процесс завершился, он всегда отдаёт код завершения системе, вот и возможность выделять память уже использованную процессами...

elf/2
29.03.2005, 17:10
Принцип работы сборщика мусора заключается в том, что выбираются все глобальные статические указатели, и помечаются все достижимые из них области памяти. Все недостижимые области памяти являются мусором.
теперь представим, что в выделенной области памяти мы храним указатели на другие динамически выделенные области. без наличия понятия объект и тип объекта корректное освобождение памяти в этом случае не представляется возможным.

Ассемблер - не очень удобный язык для программирования совместно со сборкой мусора. Следует использовать язык более высокого уровня.
я об этом же... ассемблер совсем не подходит для автоматической сборки мусора. языков более высокого уровня я на Спекки пока не видел :(

elf/2
29.03.2005, 17:12
когда программа самоликвидировалась, необходимо освободить всю принадлежащую ей память
это безусловно нужно, но довольно далеко от темы данной ветки

GriV
29.03.2005, 17:13
Не стоит смеяться. Это очень полезный вопрос. В связи с перекладыванием функций выделения памяти на ось, туда же падает освобождение памяти. Во всяком случае, когда программа самоликвидировалась, необходимо освободить всю принадлежащую ей память.

Здесь имеет место другое: подразумевается что указанный ЯВУ работает поверх нормальной системы.
А тогда сам вопрос отпадает.
С другой стороны, если считать что в этом смысле ЯВУ заменяет собой систему, то получается ещё лучше: вариации на тему "хотел написать оболочку, написал ОСь"

captain cobalt
29.03.2005, 17:23
теперь представим, что в выделенной области памяти мы храним указатели на другие динамически выделенные области. без наличия понятия объект и тип объекта корректное освобождение памяти в этом случае не представляется возможным. Сборщик мусора должен иметь информацию обо всех указателях. В том числе находящихся внутри объектов. При работе он ищет все достижимые через указатели объекты, в том числе через цепочки указателей внутри объектов.
Таким образом, корректная сборка мусора возможна.

elf/2
29.03.2005, 18:02
Сборщик мусора должен иметь информацию обо всех указателях. В том числе находящихся внутри объектов. При работе он ищет все достижимые через указатели объекты, в том числе через цепочки указателей внутри объектов.
Таким образом, корректная сборка мусора возможна.
ближе к коду:
1. мы попросили у системы 100 байт
2. нам вернули указатель на выделенную память в регистре HL
3. это был временный буфер, мы его использовали и он нам больше не нужен

что мы должны сделать дальше чтобы сборщик мусора понял что эту память можно забирать?

SMT
29.03.2005, 18:12
ближе к коду:
1. мы попросили у системы 100 байт
2. нам вернули указатель на выделенную память в регистре HL
3. это был временный буфер, мы его использовали и он нам больше не нужен

что мы должны сделать дальше чтобы сборщик мусора понял что эту память можно забирать?указатели должны быть типизированы или каждый блок памяти иметь маркер типа или размера блока

captain cobalt
29.03.2005, 18:24
ближе к коду:
1. мы попросили у системы 100 байт
2. нам вернули указатель на выделенную память в регистре HL
3. это был временный буфер, мы его использовали и он нам больше не нужен

что мы должны сделать дальше чтобы сборщик мусора понял что эту память можно забирать? Для упрощения конструкции лучше, чтобы все указатели находились в памяти, то есть в данном случае нужно чтобы либо сразу после этого выделения HL сразу атомарно записывался в память, где его найдёт сборщик мусора, либо чтобы функция выделения памяти сама записывала указатель в память.

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

Vitamin
29.03.2005, 18:41
Сборка мусора - это способ автоматического управления памятью, применяемый в большинстве функциональных языков программирования и в некоторых императивных языках. В том числе в технологиях Java и .NET от известных транснациональных корпораций.

указанные языки хранятся в памяти в виде байт-кода. а выполнением занимается виртуальная машина. очистка неиспользуемой памяти идет отдельным потоком (т.е. как минимум нужна многозадачность). плюс к тому, очистка происходит в несколько этапов, т.н. поколений. если блок памяти не выдержал проверки, он убивается. реализация данного дела довольно сложна, поэтому должна быть не частью ОС, а частью реализации ЯВУ (если таковые будут), потому как автоматическая сборка мусора довольно ресурсоемкое занятие.



Автоматическое управление памятью с помощью сборки мусора налагает некоторые ограничения на программы (например, требование ссылочной прозрачности всех структур данных).
Однако радикально поднимает удобство программирования.

для написания программ на ЯВУ- это сплошное удовольствие. а представь каково это на асме? двойная адресация (адресуем ячейку, в которой хранится адрес выделенного блока памяти) будет замедлять и без того невысокую скорость работы программ. плюс трата системных ресурсов на периодическую проверку и сборку этого мусора.



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

Знахарь
29.03.2005, 19:06
А как насчет скорости ?

Ну, на спеке так не развернешься, как пишут... В любом случае кодер знает сколько памяти сожрет его прога. Значит и в запросах можно оперировать реальными числами. Т.е.
1. говоришь, что надо тебе 3х16кб страницы.
2. Ось говорит: на и вешает на эти 3 страницы флажок занято. при этом дает тебе номерок
3. говоришь "у меня всё"
и даешь ей номерок и код "у меня всё"
4. ось говорит ОК и снимает флажки занято.

dll

принцип тот же, нужен тебе dll:

1. берешь список процессов (программ/модулей.. как угодно) оси ищешь название/код (версию) dll (а как еще ?)
2.нету такого. Ага. говришь оси нужна еще скжаем страница под эту dll.
3. ось выдает страницу.
4. грузишь dll туда но в список процессов вносишь ее код/ имя.
сам можешь закрываться, dll останется, но!

на таких ресурсах вешать 1 байт - колво пользующихся. Т.е. 1 прога юзает dll -1 ,3 юзают - 3. никто не юзает - 0 но из списка убирать ресурс только тогда, когда его страницу кому-то отдали.

А вот теперь и сбощик мусора: нет его как такового. Он просто должен в первую очередь выдавать память из под приложений, а если ее не хватает, то из под неиспольз. dll. И обновлять список приложений, ресурсов (процессов) чтоб не юзались ресурсы.

Такой вот простой менеджер памяти с уборкой мусора. Ну а теперь как реализовать реально хотя бы такое... И сколько оно будет жрать ресурсов само по себе ?

Знахарь
29.03.2005, 19:09
Vitamin! Ты тут? А ну говори, что нибудь по этому поводу! Ты ж этим занимался

GriV
29.03.2005, 19:29
Чтобы схема заработала надо лобзиком дрова напилить!

Vitamin
29.03.2005, 19:46
Чтобы схема заработала надо лобзиком дрова напилить!
сказал как в лужу пёрднул %)

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

для смотрящих в сторону C# и Java, где сабж реализован, замечу, что данные языки являются производными от базового- С/С++, где есть функции как выделения, так и освобождения памяти.

captain cobalt
29.03.2005, 19:57
указанные языки хранятся в памяти в виде байт-кода. а выполнением занимается виртуальная машина. очистка неиспользуемой памяти идет отдельным потоком (т.е. как минимум нужна многозадачность). плюс к тому, очистка происходит в несколько этапов, т.н. поколений. если блок памяти не выдержал проверки, он убивается. Это детали реализации данных конкретных технологий. Существуют и другие подходы. Можно выбрать более подходящий.

реализация данного дела довольно сложна, поэтому должна быть не частью ОС, а частью реализации ЯВУ (если таковые будут) Известно, что среды со сборкой мусора плохо работают поверх платформ с монопольным захватом памяти. Они либо захватывают очень много памяти, притесняя другие программы (а в системах с виртуальной памятью с подкачкой могут приводить к трэшингу), либо вынуждены использовать более медленные копирующие уплотняющие сборщики мусора, чтобы освобождаемую из под мусора память можно было сливать в большие блоки и отдавать нижележащей системе.

Я совершенно не могу себе представить, как можно на Speccy запустить параллельно несколько сборщиков мусора. Ведь каждому понадобится собственная память "под мусор". А памяти и так не хватает. Поэтому - если сборку мусора реализовывать - но на самом низком уровне исполнения. Чтобы все использовали один сборщик мусора.

потому как автоматическая сборка мусора довольно ресурсоемкое занятие. А насколько ресурсоёмкая?
Если предположить, что вся память полностью заполнена указателями, и нет никаких других данных, то сборщику мусора придётся просканировать лишь один раз всю память. В действительности же помимо указателей в памяти находятся также полезные данные, а доля указателей невелика. Можно ожидать, что сборщик мусора будет работать доли секунды.

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

А как происходит при "обычном программировании"? Откуда адреса появляются в регистрах?

плюс трата системных ресурсов на периодическую проверку и сборку этого мусора.
А как происходит без сборки мусора?
Классические алгоритмы управления динамической памятью тоже при каждом выделении перебирают список свободных блоков, выбирая подходящий. Это тоже в плохих ситуациях может оказаться долго.

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

elf/2
29.03.2005, 20:00
указатели должны быть типизированы или каждый блок памяти иметь маркер типа или размера блока
что такое типизированные указатели в асме?
какое влияние оказывает наличие маркера типа и размера блока на возможность его освобождения?

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

где в асме переменные и области видимости?

GriV
29.03.2005, 20:22
что такое типизированные указатели в асме?
какое влияние оказывает наличие маркера типа и размера блока на возможность его освобождения?

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

где в асме переменные и области видимости?

Похоже что коллега не понимает твой вопрос. Подразумевается, что используется ЯВУ (язык высокого уровня), соответственно имеется структура, имеется указатель структуры и т.д.
Вообще я так понимаю, что сборщик мусора есть свойство/метод ОСи (её менеджера памяти), который по этим структурам и осуществляет очистку, поэтому сборщик и ЯВУ никогда не развиваются по отдельности, а идут в ногу.

Vitamin
29.03.2005, 20:22
Это детали реализации данных конкретных технологий. Существуют и другие подходы. Можно выбрать более подходящий.
Известно, что среды со сборкой мусора плохо работают поверх платформ с монопольным захватом памяти. Они либо захватывают очень много памяти, притесняя другие программы (а в системах с виртуальной памятью с подкачкой могут приводить к трэшингу), либо вынуждены использовать более медленные копирующие уплотняющие сборщики мусора, чтобы освобождаемую из под мусора память можно было сливать в большие блоки и отдавать нижележащей системе.

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



Я совершенно не могу себе представить, как можно на Speccy запустить параллельно несколько сборщиков мусора. Ведь каждому понадобится собственная память "под мусор". А памяти и так не хватает. Поэтому - если сборку мусора реализовывать - но на самом низком уровне исполнения. Чтобы все использовали один сборщик мусора.
А насколько ресурсоёмкая?

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



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

советую почитать статьи по ускорению работы с памятью для ЯВУ, не поддерживающих сабж



Опять же - насколько?
Загрузив указатель из памяти в регистры можно потом многократно обращаться к блоку памяти, пока указатель находится в регистрах.

А как происходит при "обычном программировании"? Откуда адреса появляются в регистрах?

сравни:
call allocate ;hl-addr
ld (block1),hl
ld de,to
ld bc,len
ldir ;something like this

или

call allocate
ld (block1),hl
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ld de,to
ld bc,len
ldir

вроде мелочь, а неприятно.



А как происходит без сборки мусора?
Классические алгоритмы управления динамической памятью тоже при каждом выделении перебирают список свободных блоков, выбирая подходящий. Это тоже в плохих ситуациях может оказаться долго.
Ну так ведь речь не о начинающих программистах. Имея дисциплину, можно потом "правильно программировать" и со сборщиком мусора.

сравним еще раз:
без сборщика:
при выделении происходит перебор всех блоков и выбор первого подходящего или наиболее подходящего (две разные стратегии выделения памяти)
при освобождении просто происходит вставка в связный список описателя свободного блока

со сборщиком:
при выделении (см. пред. вариант)
процедура освобождения вызывается только при отсутствии необходимости в выделенном блоке и совпадает с аналогичной процедурой пред. варианта.
НО! затраты (периодические) на просмотр _всего_ списка блоков для поиска кандидатов на удаление. единственное облегчение- просматривается не список блоков, а список указателей на блоки (а хрен редьки, как известно, не слаще %) )



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

captain cobalt
29.03.2005, 21:35
повторюсь еще раз, память можно освободить тогда когда переменная содержащая указатель на нее вышла из области видимости...
Это не годится для динамических связных структур данных.

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

предложенная GriV'ом и мной система работы с памятью базируется на следующем- для кучи выделяется большой кусок памяти (сплошной естесно) и просто рулится стандартным системным менеджером кучи, который не поддерживает сборку мусора. а разработчик имеет возможность прикрутить к этому блоку любой другой менеджер. хоть с автоматической сборкой подоходнего налога. но это уже другое дело.
Ещё раз: мусор, образовавшийся в одном блоке, не сможет быть утилизирован в пользу другого блока.

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

советую почитать статьи по ускорению работы с памятью для ЯВУ, не поддерживающих сабж
На какую тему?
Сборщик мусора встаёт поперёк дороги каким-то приёмам оптимизации?

сравни:
call allocate ;hl-addr
ld (block1),hl
ld de,to
ld bc,len
ldir ;something like this

или

call allocate
ld (block1),hl
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ld de,to
ld bc,len
ldir

вроде мелочь, а неприятно.
Можно спроектировать такой интерфейс распределителя памяти, при котором он одновременно записывает адрес в память и загружает в HL. Тогда этот клочок кода превратится в

LD HL,block1
CALL allocate
LD DE,dest
LD BC,len
LDIR

Весьма симпатично. ;)

НО! затраты (периодические) на просмотр _всего_ списка блоков для поиска кандидатов на удаление. единственное облегчение- просматривается не список блоков, а список указателей на блоки (а хрен редьки, как известно, не слаще %) )
Возможны также реализации, при которых просматриваться будут указатели только на живые блоки.

Существуют также ситуации, при которых со сборщиком мусора будет быстрей. Например, если памяти хватило на всё, то можно не тратить время на освобождение. Образуется мусор, который "на досуге" уберём.

AlexCrush
29.03.2005, 22:03
Я считаю что пытаться реализовать автосборку мусора это как учиться производить ракеты, не умея делать автомобили. Начать надо (имхо) с реализации самой простой надстройки над asm'ом - это C. На асме полноценную ось никогда не написать, если и написать то надо много временнЫх ресурсов (люди*годы)... Будут полноценные malloc и free - тогда можно и о большем думать...

elf/2
29.03.2005, 22:28
Вообще я так понимаю, что сборщик мусора есть свойство/метод ОСи
неправильно понимаешь :) вот в windows и linux нет сборщиков мусора, а в Java и .NET которые работают под этими осями есть

captain cobalt
29.03.2005, 22:41
Однако, ничто не мешает сделать сборщик мусора свойством оси. ;)

elf/2
29.03.2005, 22:53
пара комментариев ко всему треду:
1. для реализации сборки мусора не нужна многозадачная ось или потоки. никто не мешаеть позвать его автоматически в тот момент когда кончилась память (из системной функции new). другой вариант, пользовательская программа может сама время от времени звать сборщика (тогда когда она считает нужным: в момент ожидания пользовательского ввода, после окончания ресурсоемкого куска)
2. сборка мусора никак не связана с виртуальными машинами/байткодом. есть библиотеки для C++ реализующие сборку для некоторых частных случаев

ну и хочется вернуться к главному _КАК_ это можно реализовать на спекке? считаем что у нас есть: АСМ и ОСЬ с хорошим менеджером памяти...
для того чтобы сборка заработала нам надо знать где выделили память, сколько и когда она освободиться. на первые два вопроса нам ответит менеджер памяти. А кто ответит на последний?
все еще предлагаю решить простейшую задачу:
1. программа попросила 200 байт памяти, вызвав системную функцию new/malloc
2. указатель на блок памяти нам вернули (в HL или записали куда-то еще в память)
3. мы этот блок использовали и он нам больше не нужен

как сборщик памяти сможет это понять и вернуть память в систему?

или в терминах captain cobalt в какой момент времени сборщик мусора поймет что данный блок "не является достижимым по цепочкам указателей начиная с глобальных статических указателей"?

elf/2
29.03.2005, 22:58
повторюсь еще раз, память можно освободить тогда когда переменная содержащая указатель на нее вышла из области видимости...
Это не годится для динамических связных структур данных.
годиться :) поскольку для того чтобы начать освобождение динамической связной структуры данных надо понять когда объект ее представляющий (или переменная указывающая на ее начало) вышел из области видимости.
только после этого по цепочке куски этой структуры начинают помечаться как неиспользованные по тому принципу что ты описывал (наличие живых ссылок)

Vitamin
29.03.2005, 23:08
Это не годится для динамических связных структур данных.

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

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



Ещё раз: мусор, образовавшийся в одном блоке, не сможет быть утилизирован в пользу другого блока.

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



Ничего не боюсь! :D
Одна куча на всю систему.
Со сборщиком мусора.
Кому не надо, не использует его.

одна куча на всю систему может быть только в нижней памяти. да и то она принадлежит системе. а у каждого процесса своя куча, которая рулится ЛЮБЫМ менеджером. по умолчанию- системным (без сборщика)



На какую тему?
Сборщик мусора встаёт поперёк дороги каким-то приёмам оптимизации?

в нашем случае, стандартный менеджер памяти (без сборщика) встал поперек дороги твоему менеджеру со сборщиком. хотя это не так



Можно спроектировать такой интерфейс распределителя памяти, при котором он одновременно записывает адрес в память и загружает в HL. Тогда этот клочок кода превратится в

LD HL,block1
CALL allocate
LD DE,dest
LD BC,len
LDIR

Весьма симпатично. ;)

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

плюс 2 байта на каждый указатель на блок. плюс дополнительное время на разыменование указателей. следует применять только в тех случаях, когда овчинка стоит выделки



Существуют также ситуации, при которых со сборщиком мусора будет быстрей. Например, если памяти хватило на всё, то можно не тратить время на освобождение. Образуется мусор, который "на досуге" уберём.
а насколько ты думаешь будет использоваться "куча" программистами, которые до этого с ней никак не работали? довольно большая часть методов, требующих динамическую память, прекрасно решаются в статической

Vitamin
29.03.2005, 23:13
пара комментариев ко всему треду:
1. для реализации сборки мусора не нужна многозадачная ось или потоки. никто не мешаеть позвать его автоматически в тот момент когда кончилась память (из системной функции new). другой вариант, пользовательская программа может сама время от времени звать сборщика (тогда когда она считает нужным: в момент ожидания пользовательского ввода, после окончания ресурсоемкого куска)
2. сборка мусора никак не связана с виртуальными машинами/байткодом. есть библиотеки для C++ реализующие сборку для некоторых частных случаев

насколько я помню, вопрос был в том, нужна ли реализация сборщика мусора на уровне ОС. предложенная архитектура может поддерживать любой менеджер памяти (на уровне процесса), будь то списковый, метод близнецов или зональный с пресловутым сборщиком мусора.

captain cobalt
29.03.2005, 23:15
для реализации сборки мусора не нужна многозадачная ось или потоки. никто не мешаеть позвать его автоматически в тот момент когда кончилась память (из системной функции new). Абсолютно верно. ;)

другой вариант, пользовательская программа может сама время от времени звать сборщика (тогда когда она считает нужным: в момент ожидания пользовательского ввода, после окончания ресурсоемкого куска) Абсолютно верно. ;)

сборка мусора никак не связана с виртуальными машинами/байткодом. есть библиотеки для C++ реализующие сборку для некоторых частных случаев Абсолютно верно. ;)

для того чтобы сборка заработала нам надо знать где выделили память, сколько и когда она освободиться. на первые два вопроса нам ответит менеджер памяти. А кто ответит на последний? Сборщику мусора необходимо сообщить обо всех существующих указателях.

все еще предлагаю решить простейшую задачу:
1. программа попросила 200 байт памяти, вызвав системную функцию new/malloc
2. указатель на блок памяти нам вернули (в HL или записали куда-то еще в память)
3. мы этот блок использовали и он нам больше не нужен

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

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

Будут полноценные malloc и free - тогда можно и о большем думать... А можно поднатужиться, и сразу родить сборщик мусора. Тогда и free не понабодится. ;)

Vitamin
29.03.2005, 23:27
А
Сборщик мусора знает обо всех указателях. Для того, чтобы "сообщить", что память больше не нужна, нужно в указатель в памяти записать другое значение (например, нулевой указатель - ни на что не указывающий). Когда сборщик мусора при следующем запуске не найдёт живых указателей на блок памяти, он объявит его мусором.

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

captain cobalt
29.03.2005, 23:32
пожалуй, это одна из немногих ситуаций, где нужен сборщик. но с другой стороны, рекурсия не так широко используется при программировании на асме С третьей стороны, сборщик мусора особо не мешает при "обычном" программировании. ;)

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

одна куча на всю систему может быть только в нижней памяти. да и то она принадлежит системе. а у каждого процесса своя куча, которая рулится ЛЮБЫМ менеджером. по умолчанию- системным (без сборщика) Что-то я сомневаюсь, что обоснованно давать каждой задаче по куче. По той же причине перерасхода памяти с невозможностью перераспределения.

в нашем случае, стандартный менеджер памяти (без сборщика) встал поперек дороги твоему менеджеру со сборщиком. хотя это не так Да здравствует объединённый распределитель памяти! :)

плюс 2 байта на каждый указатель на блок. плюс дополнительное время на разыменование указателей. следует применять только в тех случаях, когда овчинка стоит выделки Не вижу проблемы разыменования указателей. Нужно лишь, чтобы экземпляр указателя существовал в памяти. Обращатся по указателю можно, загрузив его в регистры. Повторю вопрос: откуда "берутся" указатели при "обычном" программировании, если не из памяти?

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

captain cobalt
29.03.2005, 23:41
а какая разница между принудительным освобождением памяти или корректировкой указателя на указатель? все одно надо сообщать системе что блок не нужен. только в первом случае все происходит гораздо быстрее и эффективнее Принудительное освобождение памяти - это вызов процедуры, которая наверняка выполнит как минимум одну запись в память, а потом ещё и возврат, а если вызов ещё будет маршрутизироваться через RST или подобные программные шлюзы... При изолированном рассмотрении - не эффективнее. ;)

Более того, сумма накладных расходов на вызов процедуры явного освобождения может запросто стать сопоставимой со временем работы сборщика мусора. ;)

А сборщик мусора позволяет автоматически разрешать зависимости в динамических структурах данных со сложной структурой. ;)

Vitamin
30.03.2005, 00:11
Что-то я сомневаюсь, что обоснованно давать каждой задаче по куче. По той же причине перерасхода памяти с невозможностью перераспределения.

ты забыл о спектрумовской структуре памяти. забыл о том что одновременно адресовать можно только 64 кило и не больше. причем из них приложению принадлежит максимум 16. или ты думаешь что 16 кило нижней памяти хватит на кучу для системы и для всех процессов? сильно в этом сомневаюсь.... да и к тому же защищенность практически никакая в таком случае



Но динамическое выделение (распределение) памяти в любом случае понадобится.
с этим никто не спорит. вопрос в освободительской политике %)

Vitamin
30.03.2005, 00:16
Принудительное освобождение памяти - это вызов процедуры, которая наверняка выполнит как минимум одну запись в память, а потом ещё и возврат, а если вызов ещё будет маршрутизироваться через RST или подобные программные шлюзы... При изолированном рассмотрении - не эффективнее. ;)

а если точнее, то вставит в список новый элемент. и все.
и причем тут маршрутизация при возврате из функции? вложенные вызовы в таком случае не используются. да и без рст обойтись уже решили вроде как...



Более того, сумма накладных расходов на вызов процедуры явного освобождения может запросто стать сопоставимой со временем работы сборщика мусора. ;)

А сборщик мусора позволяет автоматически разрешать зависимости в динамических структурах данных со сложной структурой. ;)
а теперь давай свалим все в одну кучу чтоб посмотреть у какого метода чего больше.
без сборщика:
на N блоков памяти имеем N вызовов освобождения.
все.

со сборщиком:
на N блоков памяти имеем N вызовов освобождения, N указателей на блоки, N коррекций этих указателей, М просмотров цепочек (при периодической проверке живых блоков)

что быстрее?

captain cobalt
30.03.2005, 00:43
ты забыл о спектрумовской структуре памяти. забыл о том что одновременно адресовать можно только 64 кило и не больше. причем из них приложению принадлежит максимум 16. или ты думаешь что 16 кило нижней памяти хватит на кучу для системы и для всех процессов? сильно в этом сомневаюсь.... да и к тому же защищенность практически никакая в таком случае Я подразумеваю одну большую кучу в верхних страницах, к которым обращается код из нижней памяти.

А что? Делать кучи по одной странице 16К? Кучки. :) И нельзя в одной куче иметь указатель на блок в другой? Мне не нравится.

а если точнее, то вставит в список новый элемент. и все.
и причем тут маршрутизация при возврате из функции? вложенные вызовы в таком случае не используются. да и без рст обойтись уже решили вроде как... Здесь уже пошла зависимость от реализации. Но как минимум CALL и RET никуда не денутся.

а теперь давай свалим все в одну кучу чтоб посмотреть у какого метода чего больше.
без сборщика:
на N блоков памяти имеем N вызовов освобождения.
все.
А также, при ошибках программирования, утечку памяти и висящие указатели. ;)

со сборщиком:
на N блоков памяти имеем N вызовов освобождения
Откуда вызовы освобождения?

N указателей на блоки
Традиционный распределитель не будет отслеживать корректность освобождаемого указателя? Значит, будем получать крушение всей кучи при попытке повторного освобождения одного указателя.

N коррекций этих указателей, М просмотров цепочек (при периодической проверке живых блоков)
И освобождение от указанных недостатков ручного освобождения - возможность более лёгкого построения более сложных программных систем.

что быстрее?
Это не всегда абсолютный приоритет.

Vitamin
30.03.2005, 00:58
Я подразумеваю одну большую кучу в верхних страницах, к которым обращается код из нижней памяти.

А что? Делать кучи по одной странице 16К? Кучки. :) И нельзя в одной куче иметь указатель на блок в другой? Мне не нравится.

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



Здесь уже пошла зависимость от реализации. Но как минимум CALL и RET никуда не денутся.

а куда они деваются при сборщике? :)



А также, при ошибках программирования, утечку памяти и висящие указатели. ;)

хех. забудем обнулить указатель для сборщика и у нас тоже чета откудато потечет %)



Откуда вызовы освобождения?

ну сборщик их же вызывает чтобы освободить неиспользуемые блоки



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

а если будет? ;)



Это не всегда абсолютный приоритет.
в условиях жестокой ограниченности процессорных ресурсов это один из абсолютных приоритетов

captain cobalt
30.03.2005, 01:26
почитай соседний тред. куча для того и нужна чтоб ее адресовать и юзать непосредственно в прямых адресах. верхняя память достукивается через менеджер и там сборщик мусора работает на уровне "сдох процесс- освобождаем память".
Данных должно быть больше чем кода. В том числе потому, что данные могут выступать как код (например, мегакод). Поэтому должна быть возможность манипулирования большими объёмами данных без их копирования.

а куда они деваются при сборщике?
...
ну сборщик их же вызывает чтобы освободить неиспользуемые блоки Сборщик ничего не вызывает для каждого указателя. Сборщик крутит довольно простой и короткий цикл, в котором помечаются живые блоки. Оставшееся после этого является мусором.

хех. забудем обнулить указатель для сборщика и у нас тоже чета откудато потечет %)
Однако, со сборщиком мусора практически невозможно ненамеренно добиться, чтобы память систематически утекала (всё больше и больше). Обычно самое худшее - это необнулённый указатель будет удерживать некоторое постоянное количество памяти.

а если будет?
Значит ему тоже понадобится дополнительная память.

в условиях жестокой ограниченности процессорных ресурсов это один из абсолютных приоритетов Опять же, весь вопрос, каков баланс. Будет ли сборщик мусора в два раза медленнее? Или только на 20%? Умозрительно это точно не оценить.

Vitamin
30.03.2005, 01:46
Данных должно быть больше чем кода. В том числе потому, что данные могут выступать как код (например, мегакод). Поэтому должна быть возможность манипулирования большими объёмами данных без их копирования.

это означает что нижнюю память надо отдать на растерзание резидентам и приложениям. иными словами, не система будет управлять приложениями, а приложения системой. нехорошо....



Сборщик ничего не вызывает для каждого указателя. Сборщик крутит довольно простой и короткий цикл, в котором помечаются живые блоки. Оставшееся после этого является мусором.

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



Однако, со сборщиком мусора практически невозможно ненамеренно добиться, чтобы память систематически утекала (всё больше и больше). Обычно самое худшее - это необнулённый указатель будет удерживать некоторое постоянное количество памяти.

в контексте "забыл убрать- начались потери" оба метода абсолютно равнозначны. потому что можно постоянно выделять блоки и забывать обнулять указатели и память будет именно систематически утекать. все больше и больше...



Значит ему тоже понадобится дополнительная память.

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



Опять же, весь вопрос, каков баланс. Будет ли сборщик мусора в два раза медленнее? Или только на 20%? Умозрительно это точно не оценить.
прошу к ассемблеру! %)
то, что на системном уровне сборщик будет только на уровне процессов- однозначно. а вот менеджер кучи может быть ЛЮБЫМ. в том числе и со сборщиком. хотя бы потому что спецификация на большинство ЯВУ требует наличия функции освобождения памяти, а в сборщике такого нет. как говорится, убрать мы всегда сумеем!

captain cobalt
30.03.2005, 06:07
это означает что нижнюю память надо отдать на растерзание резидентам и приложениям. иными словами, не система будет управлять приложениями, а приложения системой. нехорошо.... Без полноценной аппаратной защитной памяти невозможно полноценно реализовать архитектуру юниксов. Значит, следует смотреть в сторону других архитектур операционных систем.

предположим. разумеется, что цикл будет короче чем освобождение всех блоков. при периодичной проверке выигрыш будет или нет? Ну, может быть и так и сяк. ;)
В типичных случаях сборщик мусора скорее всего будет проигрывать по суммарной скорости. Однако, есть и другие факторы.

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

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

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

то, что на системном уровне сборщик будет только на уровне процессов- однозначно. Неоднозначно.
См. выше. Сборщик мусора вообще может располагаться ниже, чем планировщик процессов.

а вот менеджер кучи может быть ЛЮБЫМ. в том числе и со сборщиком. Да, именно так.
Сборщику мусора совершенно ни к чему работать на вытесняющей многозадачности параллельно с другими, обслуживаемыми им, задачами. Он может работать только при исчерпании памяти при вызове NEW(), в рамках этой процедуры.

хотя бы потому что спецификация на большинство ЯВУ требует наличия функции освобождения памяти Так ведь у нас пока не так уж много реализовано этих самых ЯВУ. ;)

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

random
30.03.2005, 09:44
Без полноценной аппаратной защитной памяти невозможно полноценно реализовать архитектуру юниксов. Значит, следует смотреть в сторону других архитектур операционных систем.

вы сами поправитесь или вас опозорить прилюдно? =)

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

elf/2
30.03.2005, 11:34
как сборщик памяти сможет это понять и вернуть память в систему?

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

сборка мусора предназначена для того чтобы подобных ошибок не было.
ты предлагаешь сборку мусора (т.е. кучу дополнительного кода) которая от этих ошибок не защищает. тогда какой от нее толк?

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

ну и по традиции о главном :) считаем что у нас есть готовый сборщик мусора:
хотелось бы увидеть как будет лежать в памяти простой односвязный список из друх элементов + указатель на голову этого списка, чтобы при пометке этого указателя как неиспользуемого автоматически отдавалась вся выделенная память

для простоты: элемент списка содержит один байт данных, глобальный массив всех выделенных указателей изначально пуст и находится по адресу #8000, куча тоже пустая и лежит начиная с #c000
пытался нарисовать сам не смог...

Знахарь
30.03.2005, 12:33
Народ!!!! АУ!!!! Не далеко ль Вы полезли ? шо то я от ваших указателей одурел :) А как z80 одуреет ?

Может кто расписать на пальцах как это всё чудище будет работать ?

Вот надо мне не 200 байт, а скажем 70 килобайт для игры. И чтоб на прерываниях мизер системы. И чтоб оба экрана юзать... Да хрен с ним, хоть один, основной. И понятно, что не где попало память нужна... короче КАК это всё будет выглядеть реально ?

Vitamin
30.03.2005, 22:12
Без полноценной аппаратной защитной памяти невозможно полноценно реализовать архитектуру юниксов. Значит, следует смотреть в сторону других архитектур операционных систем.

а никто и не говорит что необходимо полностью передирать архитектуру юниксов. кста, есть их реализации и на машинах без аппаратной защиты. в качестве прикола приведу цитату из текстика "ОСи как сортиры" %)



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

так что считай, что у нас стенки подняты )



Ну, может быть и так и сяк. ;)
В типичных случаях сборщик мусора скорее всего будет проигрывать по суммарной скорости. Однако, есть и другие факторы.

поэтому его надо как минимум делать прицепным а не обязательным и единственным.



Для того, чтобы память систематически утекала со сборщиком мусора, необходимо специально весь мусор связывать в список, чтобы мусор оставался живым. Однако, "против" такого традиционный распределитель тем более "не поможет".

насколько я понял из твоих рассуждений, блок остается "живым" до тех пор, пока на него имеется хоть один указатель из списка указателей. ну вот и получаем- пополняем список указателей и забиваем мусором кучу. те же самые проблемы.



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

поясни. куда ниже и куда выше



Да, именно так.
Сборщику мусора совершенно ни к чему работать на вытесняющей многозадачности параллельно с другими, обслуживаемыми им, задачами. Он может работать только при исчерпании памяти при вызове NEW(), в рамках этой процедуры.

поэтому НЕ НАДО его пихать в системный уровень как обязательную часть.



Так ведь у нас пока не так уж много реализовано этих самых ЯВУ. ;)

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



Можно сначала сделать, а потом убрать, а можно сразу сделать сборщик мусора. Тогда и делать а потом убирать ничего не придётся.
ты повернул все обратно ))
я говорил насчет процедуры освобождения блока. ее мы всегда успеем убрать. главное чтоб она была в рамках стандартного спискового менеджера кучи

SfS
31.03.2005, 06:39
Вставлю свои пять копеек.

Я организовывал в программах, которые много работали с выделением-освобождением памяти следующее:

Вся динамическая память - двусвязный список. То есть каждый элемент имеет указатель на последующий и предыдущий элементы. В начальный момент времени весь список состоит из одного элемента, указывающего на самого себя.

При выделении памяти - число элементов списка увеличивается. При освобождении - уменьшается, причем соседние свободные элементы объединяются в один.

Для списка хранится указатель на его голову и текущий элемент (последний выделенный участок памяти).

Таким образом при использовании free(void* ptr) экономится время, поскольку просматривается не весь список, а только элементы, соседние с удаляемым.

Каждое пользовательское приложение имеет список выделенных ему участков памяти. При удалении приложения эти участки принудительно освобождаются. Таким образом, после удаления приложения никакого "мусора" в памяти просто не остается.

ИмХО, такой подход более расточителен по памяти, зато много головных болей устраняет.

captain cobalt
31.03.2005, 08:38
вы сами поправитесь или вас опозорить прилюдно? =) А в чём должно заключаться опозоривание? В том что

юниксов. кста, есть их реализации и на машинах без аппаратной защиты. ? :)

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

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

Таким образом, со сборщиком мусора, проблема "забыли освободить память" существует в форме "забыли избавиться от всех указателей на ненужную память". Однако, и без сборщика мусора также необходимо избавляться от указателей на ненужную память. Если их сохранять, то возникнет опасность попытки обращения к ним.

Итак, сборщик мусора превращает ошибку программирования "обращение к освобождённой памяти" в менее опасную ошибку "утечка памяти". Однако, это в любом случае ошибка. Сборщик мусора не виноват. :)

2. обратились к уже освобожденной памяти Чтобы обратиться к памяти нужно иметь указатель на неё. Сборщик мусора должен знать обо всех указателях. Если существует указатель на память, то сборщик не будет освобождать её.

сборка мусора предназначена для того чтобы подобных ошибок не было. ты предлагаешь сборку мусора (т.е. кучу дополнительного кода) которая от этих ошибок не защищает. тогда какой от нее толк? Всё-таки во многих случаях защищает.

про работу с динамическими связными структурами.
довольно часто используют такой подход: программа имеет свой менеджер памяти который берет память у системы большими кусками, а после окончания работы со структурой отдает ее сразу всю.
поскольку в таких структурах элементы одного типа - менеджер получается простой и очень эффективный. а C++ предоставляет все необходимое для его реализации (перегрузка оператора new) Осталось только где-то взять компилятор C++ -> Z80. ;)

ну и по традиции о главном :) считаем что у нас есть готовый сборщик мусора:
хотелось бы увидеть как будет лежать в памяти простой односвязный список из друх элементов + указатель на голову этого списка, чтобы при пометке этого указателя как неиспользуемого автоматически отдавалась вся выделенная память
Может кто расписать на пальцах как это всё чудище будет работать ? Это лучше всё-таки посмотреть в учебнике. Или в интернете. Там и картинки есть. :)

Вот надо мне не 200 байт, а скажем 70 килобайт для игры. И чтоб на прерываниях мизер системы. И чтоб оба экрана юзать... Да хрен с ним, хоть один, основной. И понятно, что не где попало память нужна... короче КАК это всё будет выглядеть реально ? Я подразумеваю, что будет одна куча в верхних страницах, а видимый системе код будет выполняться в нижних страницах. И сможет таким образом, обращаться ко всей куче. Поэтому всё просто - запрашиваем выделение нужного объёма на куче, и имеем к нему произвольный доступ.

Второй экран. Второй экран таким образом физически оказывается в куче. Можно сделать его как блок, существующий сразу после загрузки и располагающийся в конкретном месте физической памяти. Обращение к нему не вызывает никаких проблем.

Впрочем, это низкоуроневые вопросы, и совсем не имеют отношения к сборщику мусора. Лучше этот вопрос задать тому, у кого кучи по 16К. :)

поэтому его надо как минимум делать прицепным а не обязательным и единственным. Надо делать обязательным. :)

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

Ситуации же вроде

NEW(p);
NEW(p);

и все их вариации легко разрешаются сборщиком мусора.

поясни. куда ниже и куда выше Планировщик процессов выделяет себе для работы память используя нижележащий распределитель памяти со сборщиком мусора.

поэтому НЕ НАДО его пихать в системный уровень как обязательную часть. Но сборщик мусора эффективнее в некоторых ситуациях - в ситуациях, когда он вообще не вызывается. :) Но готов всегда придти на помощь.

ну а своим предложением обязательности сборщика ты вообще лишаешь надежды поддержать часть стандартизованных ЯВУ, реализация которых наиболее вероятна. Если вдруг внезапно появится нечто интересное со сборщиком мусора, то это может стимулировать фракцию противников сборщика мусора на написание распределителя памяти с ручным освобождением, чтобы продемонстрировать его конкурентное преимущество. :) Таким образом, все выиграют. :)

elf/2
31.03.2005, 13:53
Со сборщиком мусора достаточно выполнить только первый пункт. Сборщик мусора, не найдя на память ни одного указателя, автоматически освободит её.
давайте вернемся к истокам...

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

все еще мечтаю увидеть как будет лежать в памяти односвязный список из двух элементов

captain cobalt
31.03.2005, 14:38
что такое указатель когда мы работаем в ассемблере? нет там такого типа данных... Нету. :)

поэтому хотелось бы увидеть как реализуются указатели и какие операции для них определены Вот именно этот вопрос и хотелось обсудить с самого начала. :( Применительно к сборке мусора.

С абстрактной точи зрения указатель - это (должен быть) непрозрачный тип данных. Основная операция - разыменование. Прочие операции - присвоение, проверка на равенство\неравенство, в том числе нулевому указателю, выделение памяти с получением указателя на выделенную память.

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

elf/2
31.03.2005, 14:56
С абстрактной точи зрения указатель - это (должен быть) непрозрачный тип данных. Основная операция - разыменование. Прочие операции - присвоение, проверка на равенство\неравенство, в том числе нулевому указателю, выделение памяти с получением указателя на выделенную память.
у тебя есть идеи как это реализовать на speccy или готовая реализация?

если нет то предлагаю заморозить дискуссию до момента появления как минимум спецификации (от тебя или кого-либо другого)

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

Vitamin
31.03.2005, 18:27
А в чём должно заключаться опозоривание? В том что
? :)

загляни-ка в интернет (существуют такие специальные сайты-поисковики). вот что мне выдал один из них после пары запросов навскидку:
Inferno - виртуальный пост-Unix в кармане
http://oslab.h11.ru/index.php?mod=art&part=unix&id=001

RT-Linux
http://embedded.ifmo.ru/embedded_old/ETC/REFERAT/1998_1/RTLINUX/rtlinux.html



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

о каких НИЖНИХ СТРАНИЦАХ ты говоришь? я лично знаю всего ОДНУ машину, на которой можно подставлять страницы в адрес #8000-#bfff. и если уж на то пошло, то 16 кило (а их в НИЖНИХ СТРАНИЦАХ именно столько- 16384 байта по 8 бит каждый) маловато для приложений.
а отводить всю остальную память под кучу, которая не факт что будет использована по меньшей мере нерационально.



Надо делать обязательным. :)

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



Но сборщик мусора эффективнее в некоторых ситуациях - в ситуациях, когда он вообще не вызывается. :) Но готов всегда придти на помощь.

вот именно что в НЕКОТОРЫХ, да еще когда он не используется. при этом даже не расходует процессорного времени. блеск! логика обалденная, снимаю шляпу (вместе с джинсами). а нахрена спрашивается тогда его вообще городить, если он будет эффективнее только если не будет вызываться? ;)



Если вдруг внезапно появится нечто интересное со сборщиком мусора, то это может стимулировать фракцию противников сборщика мусора на написание распределителя памяти с ручным освобождением, чтобы продемонстрировать его конкурентное преимущество. :) Таким образом, все выиграют. :)
ты мне назови хотя бы одну ОС, где сборщик мусора реализован на системном уровне. я могу назвать только две (постарайся назвать их и по возможности дополнить список). но скажу сразу- там ВЫДЕЛИТЕЛЬ памяти настолько же сложный насколько и эффективный. и предложенная тобой схема списков выглядит очень бледно %) можешь мне поверить %)

Vitamin
31.03.2005, 18:43
Хочу поддержать использование разнонаправленных списков. Списки позволяют очень гибко работать с данными и иногда без них просто не обойтись. В моём случае я использовал не указатели на другие элементы а размер цепочек - это получается экономнее, но с расчётами предыдущих и последующих элементов. Конечно применение явных указателей расточительно, но эффективно по скорости расчётов соседних элементов.

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



Структура неявного однонаправленного списка:

2 байта - размер выделенной области.
14 Бит - флаг занятости цепочки
15 бит - флаг окончания списка.
(Наибольший размер выделяемой свободной памяти при этом 16384б.)

Выделение памяти:
LD HL,SIZE - размер
CALL ALLOC

Освобождение памяти:
LD HL,ADDR - адрес цепочки
CALL FREE

Можно применить для любой 16Кб области как в основной памяти, так и в страничной.

встречный вариант с двусвязным списком, хранящим свободные области

list_descriptor
head dw blk1
tail dw blk3 ;?
lock db 0

...
blk1 dw 0 ;previous==NULL - first one
dw blk2
...
blk2 dw blk1
dw blk3
....
blk3 dw blk2
dw 0 ;next==NULL - last one

вот и все. и хранить флаги начала/конца списка абсолютно не нужно.

пример списка применительно к менеджеру памяти. пустая куча:
head dw heap
tail dw heap
...
heap dw 0
dw 0
dw heap_len

выделили 200 байт. структура будет следующая:

head dw blk1
tail dw blk1
...
heap

;heap+200
blk1 dw 0
dw 0
dw heap_len-200

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



При применении "многозадачного" режима устанавливается "семафор" (флаг) использования и если происходит выделение памяти одной задачи, то другая будет ждать пока выделение не закончится.
Если вам интересен этот метод, то можите мне написать, я поделюсь исходниками и примерами применения в многозадачности в tasm ,если я их не посеял.... :rolleyes:
если использовать стандартные библиотеки для работы со связными списками, то в описывающей список структуре можно предусмотреть защелку для синхронизации (см. lock в пред. исходе)

captain cobalt
31.03.2005, 19:07
загляни-ка в интернет (существуют такие специальные сайты-поисковики). вот что мне выдал один из них после пары запросов навскидку:
Inferno - виртуальный пост-Unix в кармане Вот спасибо. :)
Кстати, четвёртая её версия вышла год назад, в тот же день мне довелось её скачать и пощупать. ;)
И, между прочим, там используется сборка мусора. На уровне языка Limbo, на котором она написана.

RT-Linux Туфта.

о каких НИЖНИХ СТРАНИЦАХ ты говоришь? Пять и два.

я лично знаю всего ОДНУ машину, на которой можно подставлять страницы в адрес #8000-#bfff. Я и не говорю об использовании этой возможности.

и если уж на то пошло, то 16 кило (а их в НИЖНИХ СТРАНИЦАХ именно столько- 16384 байта по 8 бит каждый) маловато для приложений.
а отводить всю остальную память под кучу, которая не факт что будет использована по меньшей мере нерационально. А вот некоторые предлагают для реализации совместного доступа к данным копировать их в разделяемую память. Это, имхо, как минимум забавно (если не сказать мегалол :) ). Более эффективно свопить код. Обоснование - кода меньше, чем данных. Впрочем, этот вопрос уже далеко уходит...

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

вот именно что в НЕКОТОРЫХ, да еще когда он не используется. при этом даже не расходует процессорного времени. блеск! логика обалденная, снимаю шляпу (вместе с джинсами). а нахрена спрашивается тогда его вообще городить, если он будет эффективнее только если не будет вызываться? ;) Чтоб был готов придти на помощь. ;)

ты мне назови хотя бы одну ОС, где сборщик мусора реализован на системном уровне. я могу назвать только две (постарайся назвать их и по возможности дополнить список). Вот, Оберон дал весьма многочисленное потомство.
А Java-рантаймов-на-голом-железе уже столько, что лень их считать.

но скажу сразу- там ВЫДЕЛИТЕЛЬ памяти настолько же сложный насколько и эффективный. и предложенная тобой схема списков выглядит очень бледно %) А я вроде и не предлагаю списков.

GriV
31.03.2005, 19:11
2Cobalt> Рекомендую тебе почитать вообще литературу по треду а также попытаться разобраться в структуре памяти и прочих ресурсов спекка, у меня создаётся ощущение что по про них (я не про сборщик мусора) ты имеешь самое общее представление.

2Moders> Необходимо закрыть тему, а то она превращается в переливание из пустого в порожнее...

captain cobalt
31.03.2005, 19:25
Рекомендую тебе почитать вообще литературу по треду а также попытаться разобраться в структуре памяти и прочих ресурсов спекка, у меня создаётся ощущение что по про них (я не про сборщик мусора) ты имеешь самое общее представление. Имею довольно неплохое представление. ;)

Необходимо закрыть тему, а то она превращается в переливание из пустого в порожнее... Тема была создана для обсуждения вопроса "как лучше сделать сборщик мусора", а превратилась в обсуждение "нужен ли сборщик мусора". :( Похоже, все общие аргументы с обеих сторон высказаны. Дальше тема пойдёт либо по кругу, либо, надеюсь, в более конструктивное русло...

Vitamin
31.03.2005, 21:29
Вот спасибо. :)
Кстати, четвёртая её версия вышла год назад, в тот же день мне довелось её скачать и пощупать. ;)
И, между прочим, там используется сборка мусора. На уровне языка Limbo, на котором она написана.

в этом пункте шел разговор про ОС без защиты памяти.



Туфта.

не важно. главное что существует. могу еще QNX припомнить.



Пять и два.

из них считай 7к уйдет на экран. а где ты собираешься ядро системы хранить? на дискетке? и как ты собираешься организовывать список во внешней памяти?



Я и не говорю об использовании этой возможности.
А вот некоторые предлагают для реализации совместного доступа к данным копировать их в разделяемую память. Это, имхо, как минимум забавно (если не сказать мегалол :) ). Более эффективно свопить код. Обоснование - кода меньше, чем данных. Впрочем, этот вопрос уже далеко уходит...

копируется лишь небольшой участок данных, с которым идет работа. причем с данными работа происходит не так часто как с кодом.



Можно просить целыми 16К страницами и там орудовать своим распределителем. :)

вот тогда ты и проси блоки ЛЮБОГО размера, от 1 до 64 секторов и там орудуй ЛЮБЫМ распределителем.



Вот, Оберон дал весьма многочисленное потомство.
А Java-рантаймов-на-голом-железе уже столько, что лень их считать.

повторяю для тех кто на бронепоезде. ОС- это операционная система. а ЯВУ- язык высокого уровня. я что именно просил назвать?



А я вроде и не предлагаю списков.

а что ты предлагал? списки указателей на выделенные блоки

captain cobalt
31.03.2005, 22:06
в этом пункте шел разговор про ОС без защиты памяти. Итак.
Спектрум - машина без аппаратной защиты памяти.
Большинство операционных систем для машин без защиты памяти использует сборщик мусора. Причина - если нет аппаратной защиты, нужна программная. Сборщик мусора - одна из составляющих программной защиты памяти. Вторая важная составляющая - строго типизированный язык высокого уровня. Эти средства пресекают практически все ошибки программирования и позволяют создавать надёжные программные системы. Надёжнее чем виндовс. Который работает с аппаратной защитой памяти.

Вывод - сборщик мусора нужен в ОС для Speccy.

из них считай 7к уйдет на экран. а где ты собираешься ядро системы хранить? на дискетке? Код сможет подкачиваться как из верхних страниц, так и действительно с дискеты. Я до сих пор считаю что выполнять основной код в нижней памяти - наиболее эффективное решение.

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

копируется лишь небольшой участок данных, с которым идет работа. причем с данными работа происходит не так часто как с кодом. Я до сих пор сомневаюсь. %)

вот тогда ты и проси блоки ЛЮБОГО размера, от 1 до 64 секторов и там орудуй ЛЮБЫМ распределителем. Это будет очень неэффективно. См. выше.

повторяю для тех кто на бронепоезде. ОС- это операционная система. а ЯВУ- язык высокого уровня. я что именно просил назвать? Всё перечисленное работает на голом процессоре и самостоятельно обеспечивает свою жизнедеятельность.

а что ты предлагал? списки указателей на выделенные блоки В любом случае внутреннее хозяйство распределителя памяти не касается его клиентов. Обычно можно сменить внутреннюю реализацию распределителя не нарушив работоспособность программ. А значит и выбрать наиболее эффективную в нужном аспекте реализацию.

Vitamin
31.03.2005, 23:02
Итак.
Спектрум - машина без аппаратной защиты памяти.
Большинство операционных систем для машин без защиты памяти использует сборщик мусора. Причина - если нет аппаратной защиты, нужна программная. Сборщик мусора - одна из составляющих программной защиты памяти. Вторая важная составляющая - строго типизированный язык высокого уровня. Эти средства пресекают практически все ошибки программирования и позволяют создавать надёжные программные системы. Надёжнее чем виндовс. Который работает с аппаратной защитой памяти.

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



Вывод - сборщик мусора нужен в ОС для Speccy.

не в ОС а в каком-либо ЯВУ, который реализуется на базе ОС



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

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



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

почитай в соседнем треде предложенную структуру организации памяти. та же дефрагментация, перемещение блоков и подкачка где угодно



Я до сих пор сомневаюсь. %)

да что ты говоришь! ты забыл про многозадачность и переключение контекстов- тебе прийдется каждый цикл диспетчеризации кидать код, в то время как для доступа к данным каждый процесс может иметь собственное окно проекции



Это будет очень неэффективно. См. выше.

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



Всё перечисленное работает на голом процессоре и самостоятельно обеспечивает свою жизнедеятельность.

асемблер тоже на голом процессоре рулит. но это же не операционка. а я тебя прошу назвать именно операционку. посмотри на название темы. я там сочетания ЯВУ не вижу чета....



В любом случае внутреннее хозяйство распределителя памяти не касается его клиентов. Обычно можно сменить внутреннюю реализацию распределителя не нарушив работоспособность программ. А значит и выбрать наиболее эффективную в нужном аспекте реализацию.
да я тебе за это уже десятый пост твержу- побайтовый менеджер может быть любым! по умолчанию используется системный без сборщика. вот и все

captain cobalt
01.04.2005, 07:02
и каким же ты образом собираешься защищать память с помощью сборщика мусора? под аппаратной защитой подразумевается генерация перехватываемых прерываний при нарушении прав доступа. если работа с менеджером идет корректно А некорректная работа может сокрушить всю систему. Некорректная работа может происходить из-за ошибок программирования. Следует постараться защититься хотя бы от некоторых ошибок.

а если некорректная работа то и сборщик не поможет Некоторые проблемы сборщик частично решает:

1. Повторное овобождение памяти.
Простые распределители могут сокрушить всю кучу при попытке повторного освобождения. Можно проверять корректность освобождаемого указателя, но это потребует некоторых дополнительных расходов.
Со сборщиком мусора операции освобождения нет. Все операции освобождения инкапсулированы внутри сборщика мусора. Довольно нетрудно добиться, чтобы они все были корректными. :) А значит можно будет не проверять их корректность. Таким образом, со сборщиком мусора все операции освобождения памяти, происходящие в системе, будут корректными.

Можно сказать, проблема некорректного освободения решена. :)

2. Обращение к освобождённой памяти.
Наверняка рано или поздно приведёт к крушению всей системы. Традиционный распределитель ничем не сможет помочь.
Сборщик мусора не будет освобождать память, пока существует возможность обращения к ней.

Можно сказать, проблема обращения к освобождённой памяти решена. :)

для однозадачной системы- да. для многозадачной (с вытесняющей многозадачностью) такое неприменимо. Неприменимо.
Долой вытесняющую многозадачность на Speccy. :)

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

асемблер тоже на голом процессоре рулит. но это же не операционка. а я тебя прошу назвать именно операционку. посмотри на название темы. я там сочетания ЯВУ не вижу чета.... Они не используют нижележащую ОС и на них можно запускать программы написанные на этих ЯВУ.

да я тебе за это уже десятый пост твержу Тоже могу повторить, что сборщик мусора поверх распределителя с монопольным захватом памяти - никуда не годится по эффективности. Ещё подробнее объяснить почему?

побайтовый менеджер может быть любым! Как насчёт того, чтобы побайтовый менеджер мог быть любым и рулил внутри блоков, управляемыми менеджером со сборщиком мусора?

Alex/AT
01.04.2005, 08:39
Тут проскакивала идея про свопинг кода. Так вот. Идея не катит :( Ибо даже если код будет специально написан, никто в большой программе типа компилятора не исключает частых вызовов в другие страницы свопа и возвратов из них. А это, сами понимаете, геморрой. Если дублировать все эти вызовы, программа распухнет "донельзя". Свопить данные проще - ибо под такой своп программу легче оптимизировать.

Vitamin
01.04.2005, 19:44
А некорректная работа может сокрушить всю систему. Некорректная работа может происходить из-за ошибок программирования. Следует постараться защититься хотя бы от некоторых ошибок.

начнем с того, что менеджер по умолчанию используется прежде всего в ядре системы. ядро должно быть написано правильно, иначе оно не будет работать не только изза менеджера памяти. и для ядра важна скорость работы. по всем этим показателям стандартный менеджер лучше. а для приложений можно и сборщик пришпилить.



Некоторые проблемы сборщик частично решает:

1. Повторное овобождение памяти.
Простые распределители могут сокрушить всю кучу при попытке повторного освобождения. Можно проверять корректность освобождаемого указателя, но это потребует некоторых дополнительных расходов.
Со сборщиком мусора операции освобождения нет. Все операции освобождения инкапсулированы внутри сборщика мусора. Довольно нетрудно добиться, чтобы они все были корректными. :) А значит можно будет не проверять их корректность. Таким образом, со сборщиком мусора все операции освобождения памяти, происходящие в системе, будут корректными.

Можно сказать, проблема некорректного освободения решена. :)

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



2. Обращение к освобождённой памяти.
Наверняка рано или поздно приведёт к крушению всей системы. Традиционный распределитель ничем не сможет помочь.
Сборщик мусора не будет освобождать память, пока существует возможность обращения к ней.

скорее не системы а процесса-хулигана и настоящего владельца памяти. повторяю еще раз- система должна быть максимально избавлена от глюков памяти. такая у нее доля



Можно сказать, проблема обращения к освобождённой памяти решена. :)
Неприменимо.
Долой вытесняющую многозадачность на Speccy. :)

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



Подавляющая часть систем со встроенным сборщиком мусора. ;)

ну назови хоть одну! слабо?



Они не используют нижележащую ОС и на них можно запускать программы написанные на этих ЯВУ.

на голом процессоре нету никакой нижележащей ОС. не увиливай от ответа



Тоже могу повторить, что сборщик мусора поверх распределителя с монопольным захватом памяти - никуда не годится по эффективности. Ещё подробнее объяснить почему?

оцени эффективность выделения памяти в твоем распределителе и в предложенном. а также как насчет возможности самостоятельно освобождать память?



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

Vitamin
01.04.2005, 19:55
Тут проскакивала идея про свопинг кода. Так вот. Идея не катит :( Ибо даже если код будет специально написан, никто в большой программе типа компилятора не исключает частых вызовов в другие страницы свопа и возвратов из них. А это, сами понимаете, геморрой. Если дублировать все эти вызовы, программа распухнет "донельзя". Свопить данные проще - ибо под такой своп программу легче оптимизировать.
ты, возможно, неправильно понимаешь смысл свопинга кода. пока есть место, выделение продолжается нормально. как только обнаруживается, что памяти не хватает, начинается поиск блоков, которые менее всего использовались (или дольше всего не использовались, зависит от стратегии) и их свопинг на диск. и выделяется память в освободившемся месте. так что если процесс выделил дофига памяти и ушел в спячку, его можно со спокойной совестью засвопить и использовать его память на другие нужды

captain cobalt
01.04.2005, 20:22
ОК. По теме больше осмысленных разговоров видимо не получится. :(

ну назови хоть одну! слабо?
на голом процессоре нету никакой нижележащей ОС. не увиливай от ответа Видимо, не понимаю вопрос (почему названное не ОС).
Можно считать сдаюсь. А что это за ОС?

А вот не возникало ли вопросов, зачем и почему там сделан сборщик мусора? Почему и зачем в Inferno - потомке Unix, способном работать на машинах без защиты памяти, используется сборщик мусора?

блеск! логика обалденная, снимаю шляпу (вместе с джинсами). (Ага! Не иначе как письками меряться!)

у тебя есть идеи как это реализовать на speccy или готовая реализация?

если нет то предлагаю заморозить дискуссию до момента появления как минимум спецификации (от тебя или кого-либо другого)

без спецификации дискуссия бессмысленна, поскольку (как мне кажется) каждый говорит о чем то своем и флейма набралось на 6 страниц... ОК. Буду думать.

Vitamin
01.04.2005, 23:51
ОК. По теме больше осмысленных разговоров видимо не получится. :(
Видимо, не понимаю вопрос (почему названное не ОС).
Можно считать сдаюсь. А что это за ОС?




Зональный (zone) распределитель памяти, используемый в системах Mach и OSF/1, обладает возможностью быстрого выделения памяти и сбора мусора.

ю.вахалия "unix изнутри", стр.561

кста, очень советую почитать. много чего интересного сможешь почерпнуть на эту тематику.


вопрос на засыпку. можно ли назвать осью прошивку микроконтроллера?


А вот не возникало ли вопросов, зачем и почему там сделан сборщик мусора? Почему и зачем в Inferno - потомке Unix, способном работать на машинах без защиты памяти, используется сборщик мусора?

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



(Ага! Не иначе как письками меряться!)

фу.... как негигиенично %)

captain cobalt
02.04.2005, 07:14
ю.вахалия "unix изнутри", стр.561

кста, очень советую почитать. много чего интересного сможешь почерпнуть на эту тематику. Да, есть у меня эта книга. но
"горе тому, кто читает только одну книгу" (с)

На правах оффтопика:
Вот мы выяснили, что в Inferno тоже сборщик мусора. Если Inferno - это ось, то почему Java OS-и - не оси? Они устроены практически точно также как Inferno, с точностью до замены dis - на JVM, а Limbo - на Java. :)
Из потомков Оберона наиболее современным и технологически совершенным является Bluebottle - http:/bluebottle.ethz.ch/ (тоже со сборщиком мусора). Является ли он осью?

вопрос на засыпку. можно ли назвать осью прошивку микроконтроллера? Не удивлюсь, если по этому поводу есть более одного мнения. :)
А можно ли микроядро назвать осью? ;)

GriV
02.04.2005, 13:07
20 против 3 достаточный показатель...

Vitamin
02.04.2005, 21:28
Да, есть у меня эта книга. но
"горе тому, кто читает только одну книгу" (с)

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



На правах оффтопика:
Вот мы выяснили, что в Inferno тоже сборщик мусора. Если Inferno - это ось, то почему Java OS-и - не оси? Они устроены практически точно также как Inferno, с точностью до замены dis - на JVM, а Limbo - на Java. :)

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



Из потомков Оберона наиболее современным и технологически совершенным является Bluebottle - http:/bluebottle.ethz.ch/ (тоже со сборщиком мусора). Является ли он осью?

про оберон не знаю абсолютно ничего, поэтому на этот вопрос ничего не могу сказать.



Не удивлюсь, если по этому поводу есть более одного мнения. :)
А можно ли микроядро назвать осью? ;)
смотря какое микроядро. если брать например изначальные варианты qnx, то с большой натяжкой. современные версии- полноценные оси.

captain cobalt
03.04.2005, 10:44
могу сказать что по моим ощущениям, ты ни одну не читал %) Неужели я кидаюсь необоснованными заявлениями?

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

так что инферно вполне можно приписать к тому списку ос со встроенным сборщиком мусора. да и то, ответь мне на вопрос- это ось обеспечивает эту сборку, или интерпретатор лимбо? Ответ на этот вопрос есть в упомянутой статье :) (мне пришлось её прочитать, чтобы посмотреть, упоминается ли там о сборщике мусора. упоминается.) Ответ - сборщик мусора является свойством распределителя памяти среды исполнения самого базового уровня.
И в инферно не "интерпретатор лимбо", а JIT-компилятор для dis.

смотря какое микроядро. если брать например изначальные варианты qnx, то с большой натяжкой. современные версии- полноценные оси. Поэтому лучше не говорить, что нечто "является осью" или "не является осью".
Например, кто-нибудь может сказать, что на машинах без защиты памяти у ОС не может быть ядра, потому что нет "режима ядра". :)

Vitamin
03.04.2005, 12:42
Неужели я кидаюсь необоснованными заявлениями?

насчет числа книжек %)



Это можно списать на недостатки технологии Java. :)

может быть, пока не пришлось близко сталкиваться с этой технологией



Ответ на этот вопрос есть в упомянутой статье :) (мне пришлось её прочитать, чтобы посмотреть, упоминается ли там о сборщике мусора. упоминается.) Ответ - сборщик мусора является свойством распределителя памяти среды исполнения самого базового уровня.
И в инферно не "интерпретатор лимбо", а JIT-компилятор для dis.

короче говоря, если инферно работает на голом проце, то сборщик встроен в ос, если поверх другой оси, то все зависит от той самой оси. так что тут еще бабушка надвое сказала



Поэтому лучше не говорить, что нечто "является осью" или "не является осью".

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



Например, кто-нибудь может сказать, что на машинах без защиты памяти у ОС не может быть ядра, потому что нет "режима ядра". :)
ну это уже маразм %)

ладно вернемся к нашим баранам. вот ты предлагаешь втиснуть побайтовый менеджер всей доступной памяти со сборщиком мусора. у меня возник ряд вопросов
-как ты собираешься бороться со страничностью памяти
-каким образом обеспечить хотя бы примитивную защиту от доступа одного процесса к памяти другого
-как обеспечить общую память с возможностью copy-on-write

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

Alex/AT
03.04.2005, 13:59
его можно со спокойной совестью засвопить
На дискетку-то? Да и даже на винт... При той организации памяти, что есть сейчас, получится геморрой. Самый настоящий. Ибо ну засвопил ты 4 кб. А они находятся в другой странице, и вообще между двумя блоками других программ. Блок использовать все равно невозможно. Что делать?

captain cobalt
03.04.2005, 23:58
ладно вернемся к нашим баранам. вот ты предлагаешь втиснуть побайтовый менеджер всей доступной памяти со сборщиком мусора. у меня возник ряд вопросов
-как ты собираешься бороться со страничностью памяти
-каким образом обеспечить хотя бы примитивную защиту от доступа одного процесса к памяти другого
-как обеспечить общую память с возможностью copy-on-write

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

Можно воспользоваться этой же моделью, выкинуть из неё всё ненужное и лишнее, и прикрутить сборщик мусора. :)

Alex/AT
04.04.2005, 19:47
Разумеется, центральная идея - обращаться к памяти косвено
Гы. По ~30-40 тактов на байт... чересчур.

captain cobalt
04.04.2005, 20:32
Гы. По ~30-40 тактов на байт... чересчур. Не совсем так. Косвеное обращение ко всему выделенному блоку, а не каждому байту.

А по поводу тактов на байт лучше рассказать тем, у кого блоки физически копируются. ;)

acidrain
04.04.2005, 21:33
Сборщик мусора - одна из составляющих программной защиты памяти. Вторая важная составляющая - строго типизированный язык высокого уровня. Эти средства пресекают практически все ошибки программирования и позволяют создавать надёжные программные системы. Надёжнее чем виндовс. Который работает с аппаратной защитой памяти.
Хммм - например мы выбрали AmigaE язык за основу всей оси, тогда спек получится ограничен одним языком, который, возможно, далеко не эффективен. Прийдется писать жабу на амиЕ, чтоб соответсвовать оси. А представь критичные по скорости проги - их как реализовывать? Тогда, проще клепать простую хард защиту памяти и иметь ее ввиду при разработке оси (т.е. разработать единый стандарт, чтоб не было потом трений), что пользователь может прикупить такой штука у дяди Васи и тада ось и спек станут супер-пупер =). Спорщик муссорА - не для спека имхо =)

Vitamin
04.04.2005, 23:26
Не совсем так. Косвеное обращение ко всему выделенному блоку, а не каждому байту.

А по поводу тактов на байт лучше рассказать тем, у кого блоки физически копируются. ;)
а ты почитай внимательнее предложения. а еще лучше, просто прочитай.
к куче имеется ПРЯМОЙ доступ, для этого она и придумывалась. а блоки копируются при доступе к верхней памяти, расширенной.

captain cobalt
05.04.2005, 06:15
Хммм - например мы выбрали AmigaE язык за основу всей оси, тогда спек получится ограничен одним языком, который, возможно, далеко не эффективен. Прийдется писать жабу на амиЕ, чтоб соответсвовать оси. А представь критичные по скорости проги - их как реализовывать? Да, именно это упоминалось как "недостатки технологии Java". Нужно иметь возможность реализовывать time-critical участки на ассемблере.

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

captain cobalt
05.04.2005, 06:15
а ты почитай внимательнее предложения. а еще лучше, просто прочитай.
к куче имеется ПРЯМОЙ доступ, для этого она и придумывалась. а блоки копируются при доступе к верхней памяти, расширенной. Вижу.

Vitamin
05.04.2005, 21:41
Вижу.
ну вот и посчитай потери на "копирование блоков туда-сюда" если приложение будет юзать всего килобайт памяти в локальной куче

и ответь пожалуйста подробнее на мои вопросы по реализации требований твоим методом (несколько постов назад)

captain cobalt
05.04.2005, 22:47
ну вот и посчитай потери на "копирование блоков туда-сюда" если приложение будет юзать всего килобайт памяти в локальной куче Да здравствует сравнение технических характеристик в наиболее благоприятных условиях. :)

и ответь пожалуйста подробнее на мои вопросы по реализации требований твоим методом (несколько постов назад) ОК.
Предположим, что размер указателя будет 16 бит. Используется модель, в которой указатель - это хэндл блока памяти на куче. Таким образом, максимум 64K блоков на куче на всю систему.

Будет системный вызов РАЗЫМЕНОВАТЬ УКАЗАТЕЛЬ, в который передаётся указатель, результат - устанавливается нужная страница и возвращается адрес блока внутри неё. Теперь блок можно адресовать напрямую. Кроме того, имеет смысл сделать вызов КОПИРОВАНИЕ из блока, указываемого одним указателем, в блок указываемый другим указателем того же типа. Это копирование может происходить из одной страницы в другую. Это нужно, чтобы сделать операции копирования явными.

-как ты собираешься бороться со страничностью памяти Видимо, имеется ввиду внутренняя фрагментация. Разумеется, с этим можно бороться, если разделять блоки по разным страницам, а при разыменовании склеивать в непрерывный блок. Однако, здесь понадобится "прозрачное" копирование, к которому я скептически отношусь. Поэтому - пока никак не собираюсь бороться. Буду рекомендовать делать размеры блоков "как можно более кратными степени двойки".

-каким образом обеспечить хотя бы примитивную защиту от доступа одного процесса к памяти другого Всё равно бесполезное занятие. Лучше даже и не пробовать. Неплохое решение - использование сильно типизированного языка высокого уровня.

-как обеспечить общую память с возможностью copy-on-write Общую память - очень просто: одна программа даёт второй программе указатель, который тут же можно использовать по назначению. Если неизвестно, какая программа завершится раньше, а какая позже - тут и развернётся сборщик мусора во всей красе. :)
COW для блоков памяти на куче? Забавно. :)
Но также вполне возможно. Конечно же понадобятся вызовы вроде "разыменовать для записи", "разыменовать для чтения", "разыменовать для чтения\записи" и т. п.

Alex/AT
05.04.2005, 22:48
ну вот и посчитай потери на "копирование блоков туда-сюда" если приложение будет юзать всего килобайт памяти в локальной куче
Относительно легко избегается... Надо просто делать динамическое распределение (я говорю про мою структуру управления памятью), тогда блок скопируется в одну из Swap-областей и, если не будет вытеснен оттуда другой задачей, так там и пролежит. А при следующем вызове свопера просто не будет копироваться. А для машин с двумя переключаемыми страницами - вообще сказка. А если системе (опять же говорю про собственный подход) удастся найти для динамического выделения с флагом Frequent найти блок памяти рядом с кодом (в одной странице) - то еще больший персик.

А насчет псевдоуказателей - это излишество. Ибо всегда "возвращать" адрес в регистре неудобно - иногда нужны фиксированные обращения, для оптимальной производительности. Да и какая нафиг сборка мусора в машине с 64к адресного пространства и метром памяти. Любой memleak 99% сгубит приложение нафиг и сразу.

captain cobalt
05.04.2005, 23:35
Относительно легко избегается... Надо просто делать динамическое распределение (я говорю про мою структуру управления памятью), тогда блок скопируется в одну из Swap-областей и, если не будет вытеснен оттуда другой задачей, так там и пролежит. А при следующем вызове свопера просто не будет копироваться. Вот и я говорю. Если только одна задача, использующая кучу на 1К, действительно, проблем никаких.

Vitamin
06.04.2005, 00:39
Да здравствует сравнение технических характеристик в наиболее благоприятных условиях. :)

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



ОК.
Предположим, что размер указателя будет 16 бит. Используется модель, в которой указатель - это хэндл блока памяти на куче. Таким образом, максимум 64K блоков на куче на всю систему.

сколько весит хэндл? каким образом они хранятся? где?



Будет системный вызов РАЗЫМЕНОВАТЬ УКАЗАТЕЛЬ, в который передаётся указатель, результат - устанавливается нужная страница и возвращается адрес блока внутри неё. Теперь блок можно адресовать напрямую. Кроме того, имеет смысл сделать вызов КОПИРОВАНИЕ из блока, указываемого одним указателем, в блок указываемый другим указателем того же типа. Это копирование может происходить из одной страницы в другую. Это нужно, чтобы сделать операции копирования явными.

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



Видимо, имеется ввиду внутренняя фрагментация. Разумеется, с этим можно бороться, если разделять блоки по разным страницам, а при разыменовании склеивать в непрерывный блок. Однако, здесь понадобится "прозрачное" копирование, к которому я скептически отношусь. Поэтому - пока никак не собираюсь бороться. Буду рекомендовать делать размеры блоков "как можно более кратными степени двойки".

"...и пилить дрова лобзиком" (С) GriV %)
если бы такое требование выполнялось, то можно запросто фигачить свой менеджер по методу близнецов и не долбаться с дефрагментацией и объединением кусков.
я имею в виду как ты будешь хранить информацию о том, что куча физически состоит из нескольких кусков размером 16к каждый, причем в любой момент времени доступ только к одному.



Всё равно бесполезное занятие. Лучше даже и не пробовать. Неплохое решение - использование сильно типизированного языка высокого уровня.

ну вообще-то в данной теме идет обсуждение ИМЕННО многозадачной ОС. и если твоя система (глобальная куча) не катит в таких условиях, имеет смысл применить ее на уровень ниже, как я тебе уже целую неделю советую %)



Общую память - очень просто: одна программа даёт второй программе указатель, который тут же можно использовать по назначению. Если неизвестно, какая программа завершится раньше, а какая позже - тут и развернётся сборщик мусора во всей красе. :)
COW для блоков памяти на куче? Забавно. :)

а вот именно так. чтоб легко дублировать процессы и не дублировать при этом всю память сразу.



Но также вполне возможно. Конечно же понадобятся вызовы вроде "разыменовать для записи", "разыменовать для чтения", "разыменовать для чтения\записи" и т. п.
какой это смысл имеет в твоем случае- не знаю. в нашем варианте- нужно ли записывать блок из окна проекции обратно в память. там это необходимо.

далее вопрос. как реализовать подкачку? и многозадачность- вот краеугольный камень в твой огород %)

Vitamin
06.04.2005, 00:52
Относительно легко избегается... Надо просто делать динамическое распределение (я говорю про мою структуру управления памятью), тогда блок скопируется в одну из Swap-областей и, если не будет вытеснен оттуда другой задачей, так там и пролежит. А при следующем вызове свопера просто не будет копироваться. А для машин с двумя переключаемыми страницами - вообще сказка. А если системе (опять же говорю про собственный подход) удастся найти для динамического выделения с флагом Frequent найти блок памяти рядом с кодом (в одной странице) - то еще больший персик.

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



А насчет псевдоуказателей - это излишество. Ибо всегда "возвращать" адрес в регистре неудобно - иногда нужны фиксированные обращения, для оптимальной производительности. Да и какая нафиг сборка мусора в машине с 64к адресного пространства и метром памяти. Любой memleak 99% сгубит приложение нафиг и сразу.
ну это все решается на практике. потому как отличий между теорией и практикой на практике больше, чем в теории (с) ктото умный %)

captain cobalt
06.04.2005, 01:57
они же наиболее часты. класс приложений, использующих большие объемы памяти, не так уж и велик. Достаточно велик. Значительная их часть является в большой степени time-critical. И поэтому нельзя позволить себе интенсивно копировать их данные.

поэтому упор надо делать на именно локальную память. Хорошая реализация локальности - установить страницу и работать с ней. Но с возможностью так же быстро установить любую другую страницу.

мы предлагали то же самое. Ну вот.

А все отличия уже упомянуты. Конспективно вкратце:
-- хочу чтобы код был внизу а данные вверху
-- не хочу вытесняющую многозадачность
-- хочу сборщик мусора; для этого дополнительно понадобится хранение информации о типах блоков (где внутри них есть указатели)

Остальное - мелочи.

если бы такое требование выполнялось, то можно запросто фигачить свой менеджер по методу близнецов и не долбаться с дефрагментацией и объединением кусков. Я планирую сначала посмотреть, сколько там теряется на внутренней фрагментации. Вдруг дополнительные телодвижения не ст0ят свеч.

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

ну это все решается на практике. потому как отличий между теорией и практикой на практике больше, чем в теории (с) ктото умный %) В теории, между практикой и теорией разницы быть не должно.

Пойду-ка раскочегаривать z80 ассемблер, и пытаться набивать инструкции.

Vitamin
06.04.2005, 21:17
Достаточно велик. Значительная их часть является в большой степени time-critical. И поэтому нельзя позволить себе интенсивно копировать их данные.

не скажи. назову два типа приложений, которым нужнен большой объем памяти- текстовые редакторы и потоковые обработчики (видео, звук и т.д.).
первый случай не является критичным по времени. проблема в модифицировании ВСЕХ данный при сравнительно небольших изменениях (вставка нескольких байт например). решается с помощью системных функций, которые будут из нижней памяти напрямую рулить верхними страницами самым быстрым способом (например, используя дма, если он есть).
во втором случае получаем около 20-25 лишних тактов на каждый байт (копирование в окно). но! зато имеется прекрасная возможность реализовать файлы, проецируемые в память (типа в окно копируем не участок верхней памяти, а читаем напрямую с диска, процессу не суть важно).



Хорошая реализация локальности - установить страницу и работать с ней. Но с возможностью так же быстро установить любую другую страницу.

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



Ну вот.
А все отличия уже упомянуты. Конспективно вкратце:
-- хочу чтобы код был внизу а данные вверху
-- не хочу вытесняющую многозадачность
-- хочу сборщик мусора; для этого дополнительно понадобится хранение информации о типах блоков (где внутри них есть указатели)
Остальное - мелочи.

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



Я планирую сначала посмотреть, сколько там теряется на внутренней фрагментации. Вдруг дополнительные телодвижения не ст0ят свеч.
Первичная информация - куча состоит из блоков. Занятых и свободных. Каждый блок принадлежит странице.

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



В теории, между практикой и теорией разницы быть не должно.

Пойду-ка раскочегаривать z80 ассемблер, и пытаться набивать инструкции.
потому она и теория.
попробуй, узнай сколько будет "стоить" разыменование указателей в плане памяти и тактов. и стоит ли игра свеч

SfS
07.04.2005, 05:58
В теме "Менеджер памяти для многозадачной ОС" я постил спецификацию на менеджер памяти... Ее, походу, так никто и не прочитал - там есть многие вещи (копирование страниц, разыменование указателей). Короче многие пункты этой спецификации пересекаются с обсуждаемыми тут вопросами.
Если не затруднит - всетаки прочитайте, обсудим.

captain cobalt
07.04.2005, 07:10
во втором случае получаем около 20-25 лишних тактов на каждый байт (копирование в окно). но! зато имеется прекрасная возможность реализовать файлы, проецируемые в память (типа в окно копируем не участок верхней памяти, а читаем напрямую с диска, процессу не суть важно). ИМХО, ещё б0льшее витание в облаках. :)

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

вот нахрена двум абсолютно разным процессам иметь данные, перемешанные в одной области памяти Это и есть крутая фича. ;)

если каждый может иметь свою кучу и творить с ней все что угодно самым что ни на есть быстрым способом? Можно повторить, что ничто не мешает реализовать это поверх больших блоков. С произвольным-то доступом ко всей памяти.

потому она и теория.
попробуй, узнай сколько будет "стоить" разыменование указателей в плане памяти и тактов. и стоит ли игра свеч Да, попробую. ;)

В теме "Менеджер памяти для многозадачной ОС" я постил спецификацию на менеджер памяти... Ее, походу, так никто и не прочитал - там есть многие вещи (копирование страниц, разыменование указателей). Короче многие пункты этой спецификации пересекаются с обсуждаемыми тут вопросами.
Если не затруднит - всетаки прочитайте, обсудим.
Хотелось почитать, но там doc оказался. И лень было идти к машине с вордом. Но схожу.

SfS
07.04.2005, 10:10
Хотелось почитать, но там doc оказался. И лень было идти к машине с вордом. Но схожу.

В каком формате удобнее ? Если не DOC - то любой другой, где поддержаны таблицы (я сам документ делал в ОпенОффисе под Линуксом)

captain cobalt
07.04.2005, 18:40
html\xml; plaintext в шоноширинном шрифте; чистая картинка %)

Vitamin
07.04.2005, 22:38
ИМХО, ещё б0льшее витание в облаках. :)

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



Вот и хорошо. Только ведь понадобится для разных категорий программного кода реализовывать разные возможности по доступу к памяти.

в честь чего это? тебе предоставляется одна возможность осуществления доступа и другая возможность для реализации своих способов



Это и есть крутая фича. ;)

это дыра на заплатке, выражаясь языком мелкософта




Можно повторить, что ничто не мешает реализовать это поверх больших блоков. С произвольным-то доступом ко всей памяти.

и ничто не мешает ЛЮБОМУ процессу запортить кучу ЛЮБОГО другого процесса. в нашем варианте в группе риска находятся только процессы лежащие в одной физической странице



Да, попробую. ;)

ждем-с результатов. кода и метрик

SfS
08.04.2005, 07:54
Ок - то же в HTML


/home/alex/work/Speccy/SDCC/doc/Организация\ памяти.html

SfS
08.04.2005, 07:59
Не получилось) пытаюсь еще раз)

короче - html в архиве