2016-12-02 9 views
4

私はthis challengeを試していました。これは、メモリを絶えず消費するプログラムを作成する必要があります。 プログラムがメモリを継続的に消費することを拒否します

は、私は、これは簡単だろう考え出したので、私は書いた:基本的にはベクターへの無限の範囲から番号を追加します

(reduce conj [] (range)) 

。理論的には永遠に。

問題は、これは3/4GBのメモリにジャンプし、次に停止するということです。 CPUは依然として堅調に推移していますが、それ以上成長することはできません。

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

(mapv (fn [_] (A.)) (range)) 

しかし、これは、同様に同じポイントを中心に成長して停止します。私は、Javaの回答からアイデアを盗み、毎回1以上のオブジェクトを作成するためにfinalizeを上書きすることを決め

の割り当てが解除されます。

これはどのように爆発しないのですか?特に私は厳格なmapを使用しているので、メモリ内のすべてを保持すべきですか?それが「知っている限り」、リスト全体をある時点で印刷したいので、すべてを保持する必要があります。さらに、ある時点で割り当てを解除した場合、オーバーライドされたfinalizeメソッドがこれを克服するべきではないでしょうか?

誰でもここで何が起こっているのか説明できますか?私は休憩でこれを書いたので、何か見落としているかもしれませんが、私は何が見えません。 Intellij/CursiveのREPLでテストされました。

答えて

2

あなたのJVMは、ガベージコレクションの全期間を基本的に過ごしています。私のシステムでは、デフォルトのヒープサイズの制限がある〜8.7ギガバイトので、あなたのGCはこの以前にも下に滞在しようとするだろう、これはあなたを与えるものによって:あなたは-Xmx JVMオプションでこれを増やすことができ

java -XX:+PrintFlagsFinal -version | grep HeapSize 

あなたはプログラムを実際に実行し続け、ベクターに物事を追加し続けます。何が起きているのかを見るには、あなたのJVMをオプション:XX:+PrintGCDetailsで起動することをお勧めします。ヒープリミットに近づくと、JVMはフルGCを数秒間実行します。注:そのif the JVM spends too much time for the GC then it will throw and OOM error

それでも(when (zero? (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))'  
+0

ああ、感謝を。私はJavaの答えがどのように働いていたのだろう(もしそうなら)。彼らは同じ問題に遭遇すると思います。ヒープサイズの変更については言及していませんでした。それはゴルフで言及する必要があるのだろうかと思う。ああ、説明のおかげで。 – Carcigenicate

関連する問題