Идеи для сбора мусора - PullRequest
1 голос
/ 19 апреля 2011

Я работаю над игрушечным языком, который использует C ++ в качестве промежуточного языка, в настоящее время он поддерживает только три типа, все приличные из базового класса, целого числа, списка и лямбды. Все функции передают базовый класс туда и обратно. Скомпилированный код выполняется на микроконтроллере, что означает, что существуют определенные ограничения, у меня есть только 8 КБ ОЗУ, поэтому в идеале я хочу избавиться от объекта, как только я закончу с ним. Также у меня нет доступа к большинству стандартных библиотек (нет Boost, STL и т. Д.).

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

Ответы [ 3 ]

2 голосов
/ 19 апреля 2011

Сборщик мусора всегда имеет нагрузку на память и процессор, поэтому на микроконтроллере этого следует избегать. Возможно, вы захотите использовать простой старый счетчик ссылок. Работает очень хорошо для Objective-C, каждое приложение для iPhone / iPad / iPod Touch использует его и многие (большинство?) Приложений Mac. Вы делаете это так:

Ваш базовый класс объекта имеет целое число, счетчик ссылок. Как только объект выделен, счетчик устанавливается на 1. Существует метод retain, который увеличивает счетчик, и метод release, который уменьшает счетчик. Как только release заставляет счетчик достигать 0, вызывается деконструктор и объект освобождается (освобождается).

Вы должны быть осторожны, чтобы избежать сохранения циклов, то есть объектов, которые сохраняют друг друга, как на A <-> B или A -> B -> C -> A, так как счетчик ссылок не может опуститься до 0, и вы будет утечка памяти. Apple решает эту проблему путем именования и других соглашений (например, если у объекта есть делегат, делегат никогда не сохраняется).

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

1 голос
/ 22 апреля 2011

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

Для экономии памяти вы, возможно, захотите поработать с некоторой семантикой копирования при записи. То есть:

x = list('a','b','c','d')
y = x; 
// x and y point to the same list in memory
y.replace(2, 'e') 
// x and y point to different lists in memory
// those 2 lists share instances of 'a', 'b', and 'd'

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

1 голос
/ 19 апреля 2011

Мне известны два основных механизма сбора мусора:

  • Подсчет ссылок
  • Mark And Sweep

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

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

Существуют сложные алгоритмы для работы с коллекцией циклов, но более простое решение:

  • Использовать подсчет ссылок для оперативного обслуживания
  • Выполнять полную коллекцию «Mark-And-Sweep» всякий раз, когда память достигает определенного порогового значения для сбора утечек циклов
...