Я подозреваю, вам лучше всего придерживаться сборки мусора (в соответствии с JVM), если у вас нет веских причин в противном случае. Современные GC чрезвычайно быстры, универсальны и безопасны. Если вы не можете разработать свой язык так, чтобы использовать в своих интересах особый особый случай (как в одном из вышеперечисленных распределителей), то вряд ли вы победите JVM.
Единственная действительно убедительная причина, которую я вижу в настоящее время в качестве аргумента против современного GC, - это задержки, вызванные паузами GC. Это небольшие, редкие и не очень важные проблемы для большинства целей (например, я успешно написал 3D-движки на Java), но они все еще могут вызывать проблемы в очень трудных ситуациях в реальном времени.
Сказав это, все еще могут быть некоторые особые случаи, когда может иметь смысл другая схема выделения памяти, поэтому я перечислил несколько интересных вариантов ниже:
Примером очень быстрого специализированного подхода к управлению памятью является распределитель «на кадр» , используемый во многих играх. Это работает путем увеличения одного указателя для выделения памяти, и в конце периода времени (обычно визуального «кадра») все объекты отбрасываются сразу, просто возвращая указатель на базовый адрес и перезаписывая их при следующем выделении. , Это может быть «безопасно», однако ограничения времени жизни объекта будут очень строгими. Может быть победителем, если вы можете гарантировать, что все распределение памяти ограничено по размеру и действительно только для объема обработки, например один запрос к серверу.
Еще один очень быстрый подход - выделенные пулы объектов для различных классов объектов. Выпущенные объекты можно просто перерабатывать в пуле, используя что-то вроде связанного списка свободных слотов объектов. Операционные системы часто использовали такой подход для общих структур данных. Однако, опять же, вам нужно следить за временем жизни объекта и явно обрабатывать удаление, возвращая объекты в пул.
Подсчет ссылок выглядит внешне хорошо, но обычно не имеет смысла, потому что вам часто приходится разыменовывать и обновлять счетчик для двух объектов всякий раз, когда вы меняете значение указателя. Эта стоимость обычно хуже, чем преимущество простого и быстрого управления памятью, и она также не работает при наличии циклических ссылок.
Распределение стека очень быстро и может работать безопасно. В зависимости от вашего языка, можно обойтись без кучи и работать полностью в системе на основе стека. Однако я подозреваю, что это несколько ограничит ваш языковой дизайн, так что это может быть не стартером. Тем не менее, стоит рассмотреть некоторые DSL.
Классический malloc / free довольно быстрый и его можно сделать безопасным, если у вас есть достаточные ограничения на создание объекта и срок его службы, которые вы можете применить на своем языке. Примером может быть, например, если вы наложили значительные ограничения на использование указателей.
В любом случае - надеюсь, это полезная пища для размышлений!