我的Clojure应用在运行Java 8的Linux系统上表现出奇怪的行为。具体而言,当使用
httpkit
通过WebSockets与客户端通信时,内存占用似乎无限增长 - 取决于系统,进程可能会被操作系统终止。
我查看了jconsole
中的内存使用情况,并且显然是(新的)元空间不断增长。我通过向jar
传递-XX:MaxMetaspaceSize=128m
来解决了这个问题:在这种情况下,每当超过128m时,元空间内存图就会降低,程序就不会吃掉所有的内存。但这只是一个解决方法 - 我想知道为什么会出现这种增长,但我不确定该如何继续。在C++中,我会使用valgrind跟踪泄漏,但由于Java/Clojure是垃圾收集的,所以我不确定要寻找什么。
我不能100%确定它只是httpkit
代码部分的问题,但从我的测试来看,似乎是这样 - 这是一个代码摘录,在其中我监听消息,并根据消息发送包含一些数据的json对象;coreparams-atom
可以在任何时候预期具有约10个浮点条目。
(httpkit/on-receive channel (fn [data]
(let [data-map (json/read-str data)
param (first (get data-map "data"))
value (second (get data-map "data"))]
(case (get data-map "type")
; ...
"curparams" (let [tosend (json/write-str
{:type "curparams"
:data (-> @state/coreparams-atom
(assoc :timestamp (db/timestamp))
(util/keyword-replace-char ":" "_"))})]
(httpkit/send! channel tosend))
; ...
))))
系统:
- Ubuntu 14.04
- OpenJDK Runtime Environment (版本1.8.0_40-internal-b27)
- 6GB内存
- Clojure 1.6.0
- http-kit 2.1.6
在一台目前无法访问的CentOS上,同样的JVM表现出类似的行为,因此无法提供详细的规格。
:jvm-opts ["-agentlib:jdwp=transport=dt_socket"]
来完成)。 - noisesmith