【问题标题】:Does GC remove all objects after ns removal in Clojure?在 Clojure 中删除 ns 后,GC 是否会删除所有对象?
【发布时间】:2017-03-25 15:59:31
【问题描述】:

我开发了一些应用程序,它从客户端获取数据并为其创建新的ns

在应用对ns进行一些操作后,调用函数等

最后,应用程序返回了一些输出,然后我删除了 ns (remove-ns)

GC 是否会删除该 ns 中的所有数据(对象)?

另一个问题是:为每个客户端创建 ns 是否明智? 我需要将客户端彼此隔离,以免发生冲突。(并发用户)

【问题讨论】:

  • 附加一个分析器自己测试一下:)
  • 除非您保留对命名空间中引用的名称或值的引用,否则它们会被垃圾回收。现在,您真的需要为每个客户端拥有一个命名空间吗?我不知道。您是否为每个客户创建了新的符号?
  • @coredump 是的,认为这是新的会话新环境

标签: clojure functional-programming garbage-collection lisp clojurescript


【解决方案1】:

我假设,你在你的命名空间上做(remove-ns),所以如果你在clojure源代码中查看clojure.core,它会在命名空间符号上调用Namespace.remove,然后从并发哈希映射中删除。如果符号只绑定到命名空间,那么它们应该被 gc 清理掉。

查看您正在使用的版本的 clojure 代码以确保确定,如果您有疑问,最好自己测试一下,通过附加分析器来查看这些对象是否在此之后实际上被删除函数调用。

【讨论】:

    【解决方案2】:

    很遗憾,您的问题没有简单的是或否的答案。

    remove-ns[1] 的作用是调用clojure.lang.Namespace[2] 中的静态remove 方法,该方法以事务方式取消映射全局映射中从ns 名称到Namespace 对象的命名空间的符号。这使得不可能对命名空间进行新的引用,因为命名空间和完全限定的符号/变量是通过命名空间映射解析的,但它不会破坏命名空间或其内容。

    如果不存在对未映射命名空间或其内容的引用,那么是的,它将(最终)被垃圾回收。但是,这假定该名称空间中的所有 Var 都不会逃脱。如果您曾经需要/将其中一个临时命名空间中的 Vars 引用为长期存在的,那么您将在两个命名空间之间创建一个永久链接,这将导致“临时”命名空间永远不会被删除,除非它也是 ns-unmapped @ 987654323@.

    现代 JVM 使用跟踪垃圾收集器,因此只有在内存压力足以强制 GC 运行时才会对对象进行垃圾收集,并且不会再使用本身不是垃圾的对象。因此,例如,如果您在其自己的沙箱命名空间中为每个会话编译一个函数,返回该函数,调用它,然后将其丢弃并取消映射临时命名空间,可能可以正常工作,因为唯一的对临时命名空间的显式引用是返回的闭包(被丢弃)和您删除的全局命名空间映射。但确切的行为完全取决于您的应用程序的结构。

    在架构层面,可以肯定地说你做错了。 Clojure (eval) 中的编译速度很慢。您真的不应该在运行时动态生成函数,更不用说命名空间了。通过这样做,您正在为自己创建这个架构问题,因为您正在(ab)使用旨在成为全局绑定结构(命名空间和变量)的东西来保存临时绑定,然后您必须担心清理这些临时绑定。

    如果您确实需要动态绑定或堆栈本地变量,则可以使用一些结构来创建这种短暂的上下文。否则,您可能会通过重构它以更广泛地使用部分应用程序和参数上下文来大大简化您的应用程序,这属于更正常的数据使用模式并且会正常进行垃圾收集。

    【讨论】:

      猜你喜欢
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      相关资源
      最近更新 更多