私はSTの中にData.Vector.Unboxed.Mutableを通してメモリを割り当てる計算をしています。このベクトルは決して読み込まれたり書かれたりすることはありません。私が持っている問題は、私がST計算を何度も実行すると、時にはベクトルの周りのメモリを保持しているように見えることです。Haskell:ST/GCからのメモリリークは収集されませんか?
アロケーション統計:
5,435,386,768 bytes allocated in the heap
5,313,968 bytes copied during GC
134,364,780 bytes maximum residency (14 sample(s))
3,160,340 bytes maximum slop
518 MB total memory in use (0 MB lost due to fragmentation)
ここで私は私の計算と128MBのベクトルの異なる値でrunST 20倍呼び出す(再び - 、未使用のSTの外に返されたり参照されていません)。最大限のレジデンスは、基本的に私のベクトルプラス数MBの他のものを加えて、よく見えます。しかし、全体のメモリ使用量は、同時に4つのベクトルコピーがアクティブであることを示しています。これはベクトルのサイズに完全に比例します。256MBの場合、予想どおり1030MBが得られます。
1GBのベクトルを使用するとメモリが不足します(4x1GB +オーバーヘッド> 32ビット)。私は、RTSが、少なくとも割当てが失敗した時点で、GC'ingの代わりに、未使用の未参照のメモリを周りに残している理由を理解していません。 + RTS -Sで実行
は、次のことを明らかに:
ここAlloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
134940616 13056 134353540 0.00 0.00 0.09 0.19 0 0 (Gen: 1)
583416 6756 134347504 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
518020 17396 134349640 0.00 0.00 0.09 0.19 0 0 (Gen: 1)
521104 13032 134359988 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
520972 1344 134360752 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
521100 828 134360684 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520812 592 134360528 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520936 1344 134361324 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520788 1480 134361476 0.00 0.00 0.10 0.20 0 0 (Gen: 0)
134438548 5964 268673908 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
586300 3084 268667168 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
517840 952 268666340 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520920 544 268666164 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520780 428 268666048 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520820 2908 268668524 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520732 1788 268668636 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
521076 564 268668492 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520532 712 268668640 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520764 956 268668884 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520816 420 268668348 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520948 1332 268669260 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520784 616 268668544 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
521416 836 268668764 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520488 1240 268669168 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520824 1608 268669536 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520688 1276 268669204 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520252 1332 268669260 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520672 1000 268668928 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
134553500 5640 402973292 0.00 0.00 0.29 0.58 0 0 (Gen: 0)
586776 2644 402966160 0.00 0.00 0.29 0.58 0 0 (Gen: 0)
518064 26784 134342772 0.00 0.00 0.29 0.58 0 0 (Gen: 1)
520828 3120 134343528 0.00 0.00 0.29 0.59 0 0 (Gen: 0)
521108 756 134342668 0.00 0.00 0.30 0.59 0 0 (Gen: 0)
我々が〜128メガバイトを超える 'ライブバイト' を持っているようです。
+RTS -hy
プロファイルは、基本的には、我々は128メガバイトを割り当てる言う:
http://imageshack.us/a/img69/7765/45q8.png
私は単純なプログラムでこの動作を再現しようとしたが、それでもST、ベクターを含むReaderで正確なセットアップを複製すると、同じモナド/プログラムの構造などの単純なテストプログラムはこれを表示しません。私の大きなプログラムを単純化すると、結局無関係なコードを完全に削除したときの動作も停止します。
Qsの:私は本当に20のうちの4倍の周りにこのベクトルを維持
- アム?
- 「はい」の場合、実際には
+RTS -Hy
とmaximum residency
と主張していますが、この動作を停止するにはどうすればよいですか? - もしそうでなければ、なぜHaskellはそれをGC'ingせずにアドレス空間/メモリを使い果たしているのですか?この動作を止めるにはどうすればよいですか?
ありがとう!
使用されるメモリは通常、最大居住度の2倍以上です。割り当ておよび収集パターンによって異なります。したがって、使用されている合計518MBのメモリはそれほど警戒的ではありません。 GHCに、 '$ ./foo + RTS -M256M'など、使用するメモリがあまりにも多いことを伝えて、それを早く収集させるようにしてください。しかし、「runSTの外でそれに保持されている参照も真実でない可能性があります。実際には漏れがあります。そのような場合は、コードを参照する必要があります。 –
@ダニエルフィッシャー518MBは〜4倍です。 1GBベクトルのメモリ不足によるクラッシュは、GHC *がメモリを収集できないことを示していませんか? + RTS -M256Mが「ヒープ排気」で失敗します。ベクトルが作成され、Reader環境内に置かれます。それだけです。他には、ST/Readerから出た後で参照を漏らさないために何ができるかわからない。私が言ったように、私は簡単なプログラムでこの問題を再現することはできません。むしろランダムなようです。 – NBFGRTW
まあ、間違った割り当てパターンが与えられた場合、4倍が起こる可能性があります。メモリ不足のクラッシュは、GHCが現在収集すべきことを知らないことを示しているかもしれませんが、 '-M256M'は' 'heap exhausted ''を引き起こすので、何かが獣への参照を持っているように見えます。 –