gpt4 book ai didi

memory-leaks - clojure 应用程序使用 eval 泄漏内存

转载 作者:行者123 更新时间:2023-12-04 04:55:00 26 4
gpt4 key购买 nike

我的 clojure 应用程序在运行时评估在单独的 .edn 文件中定义的代码,即如果 .edn 文件发生更改,包含的函数定义将重新加载到原子中,经常用于计算。

如果不受限制,应用程序似乎会在一段时间后填满 JVM 的元空间(无边界)。堆空间使用正常。

我使用“YourKit”探查器来追踪泄漏。似乎大多数分配,包括那些分析器说“无法从垃圾收集器根访问”的分配,都来自 eval 调用:

(defn eval-edn [e params_ dynparams_]
(let [input e
pairs (seq input)]
(binding [*ns* (find-ns 'myapp.core)
moods (:moods input)
last-moods @state/moods-atom
effects (:effects input)
last-effects @state/effects-atom
params params_
dynparams dynparams_
param-stats @state/coreparam-stats]
(eval input))))

paramsdynparams 是动态变量。

.edn 文件如下所示:

{:moods {:happiness 
(* (:happiness:factor dynparams)
(* 0.5 (Math/sin (* (/ (- (:weather:temperature params 0) 10) 30)
Math/PI))))
; ...
}}

具体来说,内存快照将显示数千个 myapp.core$evalN.invoke() 类型的对象,其中 N 是每次新调用都会增加的一些索引。

我读过应该尽可能避免使用 eval,但我不知道如果没有它,我如何才能在运行时在 JAR 可执行文件中实现重新加载代码。

如何确保正确清理 eval 使用的所有内存?

最佳答案

你不应该使用 eval。它不适用于您的用例。请改用 tools.reader

https://github.com/clojure/tools.reader

详细讨论在这里:

http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html?m=1

关于memory-leaks - clojure 应用程序使用 eval 泄漏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29608685/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com