5

私のコードには、これに似た小さな部分があります(もちろん、ゼロで埋められたものの代わりに実際の行列を使用しています):

x = [rinterface.FloatSexpVector([0]*(1000**2)) for i in xrange(20)]
y = robjects.r('list')(x)

メモリリークを引き起こしているようです。

次のコードを実行する場合:

for i in xrange(10):
    x = [rinterface.FloatSexpVector([0]*(1000**2)) for i in xrange(20)]
    y = robjects.r('list')(x)
    del x
    del y
    robjects.r('gc(verbose=TRUE)')

私は得る:

Error: cannot allocate vector of size 7.6 Mb
In addition: Warning messages:
1: Reached total allocation of 2047Mb: see help(memory.size)
2: Reached total allocation of 2047Mb: see help(memory.size)
3: Reached total allocation of 2047Mb: see help(memory.size)
4: Reached total allocation of 2047Mb: see help(memory.size)

これはバグですか、それとも他にすべきことがありますか? また、変数を robjects.globalenv に入れてから、gc() の前に rm()-ing することで、名前付きの変数を作成しようとしましたが、うまくいかないようです。

Windowsでrpy 2.3devを実行していることに言及する必要がありますが、これはrpy 2.2.6を使用するLinuxでも発生します(ただし、LinuxはWindowsマシンのように32ビットではなく64ビットバージョンを実行するため、メモリが増えるだけで、私はしません2047mb エラーを取得します)

編集: R gc() が最初のコード例の問題を解決する前に gc.collect() を追加するようですが、これは私の問題を解決しませんでした-コードを深く掘り下げると、問題の原因となる行が代入にあることがわかりました次のように、値を .names に追加します。

x = [rinterface.FloatSexpVector([0]*(1000**2)) for i in xrange(20)]
y = robjects.r('list')(x)[0]
y.names = rinterface.StrSexpVector(['a']*len(y))

クリーニングの前にrinterface.NULLを置いても役に立ちません。助言がありますか?

4

2 に答える 2

2

Python が組み込み R によって割り当てられたメモリの量を認識していないため、ガベージを収集する必要があることを認識していない可能性があります。

rpy2 のドキュメントにメモリ使用量について少しあります、およびSOに関する以前の質問

あなたの編集は、何かが起こっている可能性があることを示唆しています。最善の方法は、rpy2 の bitbucket ページでバグ レポートを提出し、ここではなくそこでトラブルシューティングを続行することです。

于 2012-09-05T08:50:53.877 に答える
0

メモリリークではないと思います。私はあなたに次の視点を与えようとします:

次の例を Python シェルで試してください。

l = range(32 * 1024 * 1024)

そこで、インタプリタに 128 MB の連続したメモリ領域を割り当てさせようとします。これは機能します(私のマシンでは〜7秒かかります)

さまざまな値で遊ぶことができます (256MB でも機能します)。N = 128 * 1024 * 1024 についても試してください。この値から、私のマシンは単にハングします。私が十分に辛抱していれば、おそらく数分後にマシンを元に戻すことができたでしょう. しかし問題は、インタプリタが連続したメモリ領域の大きなチャンクを簡単に割り当てることができないということです。

同じ方法でC++で1GBのメモリを割り当てることができ、同じマシンで1秒もかからないことは言うまでもありません(8GB RAMのi7、Windows 8またはCentOS6-両方のOS-esを試しました)。Javaで試したのと同じこと。

Python ヒープ アロケータがこのように動作する理由を調査するのに時間を費やしませんでした。rpy の連中は、割り当てが多すぎるのを思いとどまらせたり制限したりしようとしたのではないかと推測することしかできません。実際には、いくつかの参照オブジェクト (4 バイト以上を占める) を含む複数の小さな配列を持つことができます。

于 2014-09-05T13:36:30.423 に答える