подсчёт ссылок

Только технические вопросы по ЯОС. Терминология и прочее - в других форумах.
Ответить
БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

подсчёт ссылок

Сообщение БудДен » 29.07.22 22:46

* создать предопределённый метод очистки по образцу Finalize
* сделать возможность вызова процедур через рефлексию, подобно PechPoAdr:
проц PechPoAdr*(w: Потоки.Писарь; xAddress, typeDescAddress : адресВПамяти);
* сделать метод "вызови процедуру для каждой ненулевой ссылки", а процедура будет из прошлого пункта - хотя бы для объектов
* куда-то нужно прилепить инфу о том, что данный объект подлежит подсчёту ссылок - к типу объекта, к экземпляру или к указателю (разбор ниже)
* поменять копирование объекта и его удаление, чтобы вызывался этот метод

Куда прилепить инфу о подсчёте ссылок?

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

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 03.08.22 12:38

Промежуточные итоги мимимизации задачи. Вводим понятие "считаемого" (RC) и "сметаемого" (GC) объектов.
  • помним цель создания считаемых объектов: внедрение баз данных в памяти. Это - гораздо проще, чем "произвольный граф объектов"
  • будут сильные и слабые указатели. Слабые нужны для указания на хозяина.
  • очистка объекта управляется счётчиком сильных указателей, удаление из памяти - суммой сильных и слабых.
  • с утечками памяти через циклы на уровне ЯП не боремся
  • для борьбы с ними создадим динамический инструмент, ищущий мусор (стандартная практика)
Теперь нужно дорешать:
  • избежим ли отдельной иерархия типов для считаемых (RC) и сметаемых (GC) контейнеров
  • могут ли считаемые объекты ссылаться на сметаемые?
  • могут ли сметаемые объекты ссылаться на считаемые?
  • насколько прозрачны в языке будут обёртки для считаемости?
  • что делать с тредами?
Кажется, что можно ответить "да" на первые 3 вопроса, но это не точно.
Последний раз редактировалось БудДен 08.08.22 14:01, всего редактировалось 3 раза.

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 03.08.22 23:48

Лис, не мешай работать.

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 04.08.22 00:11

Вариант решения недорешённого:
  • все считаемые объекты живут в одной-единственной активности (на одну библиотеку хватит)
  • ссылки между считаемыми и сметаемыми объектами осуществляются через спец.адаптеры, в т.ч. понадобится невладеющий (построенный на слабых считаемых ссылках) контейнер (список) ссылок со считаемых на сметаемые. То же в обратную сторону - потребуются финалайзеры для ссылок с сметаемых на считаемые.
  • создание ссылки с сметаемого на считаемый под капотом обменивается сообщением с тредом считаемых объектов
  • при остановке мира на сборку мусора тред считаемых тоже замирает
  • примитивы новСчит, новСмет, а также ЯАктивностьСчитаемыхОбъектовЛи?
    нов = если3(ЯАктивностьСчитаемыхОбъектовЛи?, новСчит, новСмет)
Последний раз редактировалось БудДен 08.08.22 14:02, всего редактировалось 3 раза.

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 04.08.22 21:50

В общем, пока основная заминка - с синхронизацией операций. Всё видится каким-то ущербным. Можно блокировать объект-цель ссылки, при копировании ссылки на него. Это слишком медленно и вдруг он уже будет на тот момент заблокирован чем-то? Либо сделать отдельный монитор именно для подсчёта ссылок, тогда чуть лучше, но для каждого объекта нужен отдельный монитор - слишком жирно. Либо сделать глобальную блокировку, например, использовать блокировку "ЯдернаяБлокировкаДляРаботыСКучей" - она запрашивается на каждое выделение динамической памяти. Есть также более приоритетная (наверное) ЯдернаяБлокировкаДляРаботыСПамятью.

Вторая проблема - как распределять выделения памяти между сметаемыми и считаемыми кучами - тут нужно попробовать примеры.
Последний раз редактировалось БудДен 08.08.22 14:01, всего редактировалось 1 раз.

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 07.08.22 12:44

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

Код: Выделить всё

...
			| SyntaxTree.ПредписаниеПрисвоитьЗначение делай Assign(x.куда, x.что );
...
		кон Statement;
Здесь всё ясно - при генерации кода для предписания (statement), присваивание значения вызывает процедуру Assign (кстати, не пришло ли время перевести этот модуль?)

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 07.08.22 20:36

Нашёл опцию платформы --writeBarriers, которая включена в сборках для Lin и Win, но выключена в сборке Bios. Если опция включена, то при копировании указателя или записи вызывается Heaps.MarkPointer и Heaps.MarkRecord. В чём суть этой опции - пока неясно, но сама по себе опция хороша тем, что (наверное) встроена во все интересные нам точки.

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 07.08.22 23:57

Перевожу Heaps. Тут содержатся сведения о структуре данных, выделенных на куче.

https://tvoygit.ru/budden/ja-o-s/src/br ... -памяти.md

В частности, выясняется, что запись, выделенная на куче - это последовательно лежащие RecordBlockDesc, DataBlockDesc и собственно данные записи. Массив на куче - это ArrayBlockDesc, затем ArrayDataBlockDesc, за ним - данные.

Загадочно поле heapBlock в RecordBlockDesc/ArrayBlockDesc. Надо выяснить, что там находится, и тогда уже можно будет перевести все эти сущности.

Заполняется в NewRec->NewBlock->GetFreeBlock->LazySweep->InitFreeBlock

и заполняются они нулём. Спрашивается: а зачем тогда это поле вообще нужно?

БудДен
Сообщения: 2301
Зарегистрирован: 07.10.18 14:01

Re: подсчёт ссылок

Сообщение БудДен » 08.08.22 00:23

пытался искать, где же заполняется этот heapBlock, и попалось в модуле Reflection:

Код: Выделить всё

	УкльНаЗаголовокБлокаПамяти* = укль {опасныйДоступКПамяти, неОтслСборщиком} на ЗаголовокБлокаПамяти;
	ЗаголовокБлокаПамяти* = запись
		следщ- : УкльНаЗаголовокБлокаПамяти;
		адресЭтогоБлока-: адресВПамяти; 		(* sort key in linked list of memory blocks *)
		разм-: размерМЗ;
		адресНачалаДанных-, адресЗаКонцомДанных-: адресВПамяти
	кон;

Ответить