Я пытаюсь написать свой собственный язык сценариев на C.
Вскоре я решил использовать алгоритм mark & sweep в качестве сборщика мусора. Если я правильно понимаю, мне нужно знать, каков мой корневой указатель для обхода моих объектов. Выделив эти объекты, не зная, куда поместить кучу, кажется, что я не могу найти их после разыменования.
Например,
x = 10 // int object 10 is referenced to x
y = 1.23 // double object 1.23 is referenced to y
x = 15 // previous 10 became garbage now 15 is held by x
В приведенном выше примере каждый объект (10,1.23 и 15) выделяется как структура с тегом типа и данными. Если я просто слепо размещаю их в своей куче, я не могу найти «10» после назначения «15» для «x». Тогда у меня будет утечка памяти.
Чтобы преодолеть эту проблему, я решил написать свой собственный код управления памятью. Во-первых, я выделяю свои внутренние буферы (они будут действовать до конца программы). Опять же, другой пул памяти будет выделен для запуска сборщика мусора в этой части памяти.
После того, как моя куча управления памятью будет выглядеть как
Heap : [------------------------------------------------------]
My_memory:[Internal Buffers][Object Pool][<----Not allocated---->]
Каков размер этого пула объектов? Я могу начать с любого КБ, а затем увеличить его при необходимости.
После того, как я это решил, мне нужно сделать свой собственный учет в пуле объектов. Когда происходит распределение объектов, у меня есть указатель, чтобы показать конец последнего объекта в пуле. Если для новых выделений имеется доступная память, программа просто использует этот указатель для помещения новых объектов в пул.
//After running above example
[Object Pool] : [10|1.23|15|--------->]
^
|after this point i can put my new objects
Если размер не достаточен и запрашиваемые данные не больше, чем пул объектов, я могу запустить сборщик мусора, чтобы освободить место в пуле. Каждый объект содержит свой собственный бит метки.
Mark phase >> [10|1.23*|15*] // 10 becomes garbage
Теперь проблема в том, что int-объект 10 содержит ненужные данные и фрагментирует мой пул объектов. У меня разные подходы к этой проблеме.
- Если новое распределение является объектом int, просто используйте первый пустой немаркированный объект int. ( Здесь int - просто пример, это может быть любой объект ). Тем не менее, выполнение такого поиска может вызвать большую паузу, поскольку размер пула объектов может быть большим.
- Проверьте размер, возможно, новый объект требует того же размера (, это также кажется редким ), как объект int или меньше, чем объект int (, это может создать новую фрагментацию ), напишите на это место.
- Запустите другую программу, чтобы переместить память в пул объектов. Это выглядит опасно для меня, потому что это может занять много времени, чтобы сделать работу.
Если нет места для размещения данных в пуле объектов, размер можно увеличить. Тем не менее, я могу убедиться в этом только путем сметания с начала пула объектов. Я знаю, что malloc использует свободный список для размещения моего нового распределения в доступном пространстве. Как видите, я не хочу хранить список свободного места, для этого приложения важна память.
Предположим, что мы увеличили размер пула объектов.
[Object pool]: [10|1.23*|15*,<---new data--->,...empty allocated space...]
^
| available space pointer
Когда программа будет завершена, каждая память будет передана ОС без утечки памяти.
У меня вопрос: "Имеет ли смысл такое управление памятью или я выполняю ту же работу, что и malloc?"