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 然后 rm()-ing 在 gc() 之前将它们命名为变量,但它似乎不起作用。

我应该提到我在 Windows 上运行 rpy 2.3dev 但这也发生在 rpy 2.2.6 的 linux 上(尽管由于 linux 运行 64 位版本而不是像 windows 机器那样运行 32 位,内存只是增长而我没有得到 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 shell 中尝试这些示例:

l = range(32 * 1024 * 1024)

所以我们尝试让解释器分配 128 MB 的连续内存区域。这将起作用(在我的机器上大约需要 7 秒)

您可以使用各种值(它仍然适用于 256MB);也尝试 N = 128 * 1024 * 1024;从这个值开始,我的机器就挂了。如果我有足够的耐心,我可能会在几分钟后拿回我的机器。但问题是解释器不能轻易分配大块连续的内存区域。

值得一提的是,我可以以相同的方式在 C++ 中分配 1GB 的内存,并且在同一台机器上花费不到 1 秒的时间(i7 和 8GB RAM、Windows 8 或 CentOS6 - 我尝试了两种操作系统)。我用Java尝试过同样的事情。

我没有花时间研究为什么 python 堆分配器会这样。我只能推测 rpy 人试图阻止/限制你分配太多,所以他们设置了一个下限,这样就不会发生任何不好的事情;实际上,您可以有多个较小的数组,其中包含一些引用对象(占用超过 4 个字节)。

于 2014-09-05T13:36:30.423 回答