Memory 程序拒绝持续消耗内存

Memory 程序拒绝持续消耗内存,memory,clojure,Memory,Clojure,我在尝试,这需要你写一个程序,不断消耗内存 我想这很容易,所以我写了: (reduce conj [] (range)) 它基本上是把无限范围内的数字加到一个向量中;理论上永远如此 问题是,这会跳到3/4GB内存,然后就停止了。CPU仍在努力运行,但它拒绝再变大 我决定从Java答案中偷取一个想法,并覆盖finalize,以便在每次释放对象时创建更多对象: (defrecord A [] Object (finalize [this] (mapv (fn [_] (A.)) (rang

我在尝试,这需要你写一个程序,不断消耗内存

我想这很容易,所以我写了:

(reduce conj [] (range))
它基本上是把无限范围内的数字加到一个向量中;理论上永远如此

问题是,这会跳到3/4GB内存,然后就停止了。CPU仍在努力运行,但它拒绝再变大

我决定从Java答案中偷取一个想法,并覆盖
finalize
,以便在每次释放对象时创建更多对象:

(defrecord A []
  Object
  (finalize [this] (mapv (fn [_] (A.)) (range 5)))) ; Create 5 more

(mapv (fn [_] (A.)) (range))
但这也停止了在同一点上的增长

这怎么不爆炸呢?特别是因为我使用的是一个严格的
映射
,它应该保留内存中的所有内容,不是吗?据它所知,我希望它在某个时候打印整个列表,因此它需要保留所有内容。另外,如果它在某个时候被解除分配,那么被重写的
finalize
方法不应该克服这个问题吗

有人能解释一下这是怎么回事吗?我在休息时写的,所以我可能忽略了什么,但我看不到什么。
它是在Intellij/Cursive的REPL中测试的

您的JVM基本上把全部时间都花在垃圾收集上。在我的系统上,默认堆大小的限制为~8.7GB,因此根据这一限制,您的GC将尝试更早地保持低于此限制:

java -XX:+PrintFlagsFinal -version | grep HeapSize
您可以使用
-Xmx
JVM选项增加该值

您的程序实际上将继续运行并不断向向量添加内容。我建议使用选项
:XX:+PrintGCDetails
启动JVM,以查看发生了什么。在接近堆限制后,JVM将在几秒钟内完成完整的GCs。请注意

要查看您仍在分配,只需在以下位置抛出一个
(当(零)(rem x 1e5))(println x))

java -server -Xmx2g -XX:+PrintGCDetails -cp clojure-1.8.0.jar clojure.main -e '(mapv #(cond-> % (zero? (rem % 1e4)) println) (range))'    

哦,谢谢。我想知道Java答案当时是如何工作的(如果是的话)。我想他们也会遇到同样的问题。他们没有提到更改堆大小。我想知道在高尔夫球比赛中是否有必要提到这一点。哦,谢谢你的解释。