GC удаляет все объекты после удаления ns в Clojure?

Я разрабатываю какое-то приложение, которое получает данные от клиента и создает новые ns для этого.

После того, как приложение делает некоторые манипуляции в nsвызова функций и т. д.

Наконец приложение возвращает какой-то вывод, и я удаляю ns впоследствии (remove-ns)

GC удаляет все данные (объекты) в этих нс?

Другой вопрос: стоит ли создавать ns для каждого клиента? Мне нужно изолировать клиентов друг от друга, чтобы не было конфликтов.(Параллельные пользователи)

2 ответа

Решение

К сожалению, нет простого ответа "да" или "нет" на ваш вопрос.

Какие remove-ns [1] делает это вызывает статический remove метод в clojure.lang.Namespace [2], который транзакционно отображает символ, именующий пространство имен в глобальном отображении из имен ns в объекты пространства имен. Это делает невозможным создание новой ссылки на пространство имен, поскольку пространства имен и полностью определенные символы / переменные разрешаются с помощью сопоставления пространства имен, но это НЕ разрушает пространство имен или его содержимое.

Если не существует ссылок на неотображенное пространство имен или его содержимое, то да, оно (в конечном итоге) будет собираться мусором. Однако это предполагает, что все переменные в этом пространстве имен никогда не исчезают. Если вам когда-либо понадобится / отослать Vars из одного из этих временных пространств имен в долгоживущий, вы создаете постоянную связь между этими двумя пространствами имен, что приведет к тому, что "временное" пространство имен никогда не будет удалено, если только оно не будет ns-unmapпед [3].

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

На архитектурном уровне можно с уверенностью сказать, что вы делаете это неправильно. Сборник в Clojure (eval) медленный. Вы действительно не должны динамически генерировать функции, не говоря уже о пространствах имен во время выполнения. Таким образом, вы создаете эту архитектурную проблему для себя, потому что вы (ab) используете то, что намеревается быть глобальной связывающей структурой (пространства имен и переменные) для хранения временных привязок, которые вам придется беспокоиться об очистке.

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

Я полагаю, вы делаете (remove-ns) на вашем пространстве имен, так что если вы посмотрите на clojure.core в исходном коде clojure он вызывает Namespace.remove на символе пространства имен, который, в свою очередь, удаляется из параллельной хэш-карты. Если символы связаны только с пространством имен, они должны быть очищены gc.

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

Другие вопросы по тегам