清除rpy2使用的内存

8
我该如何清除通过rpy创建的对象(以及它们占用的内存)?
import rpy2.robjects as r
a = r.r('a = matrix(NA, 2000000, 50)')
del a    #if I do this, there is no change in the amount of memory used
r.r('rm(list=(ls(all=TRUE)))') # Same here, the objects disappear, but the memory is still used

不幸的是,在我的应用程序中,内存使用量会增加,直到没有足够的内存,然后它会崩溃... 来自rpy2 docs

对象本身仍然可用, 并且在Python中删除foo之前,受到R垃圾回收的保护

但即使这样做:
import rpy2.robjects as r
a = r.r('a = matrix(NA, 2000000, 50)')
r.r.rm('a')
del a
r.r.gc()

不释放所使用的内存...

编辑:rpy2 2.0,Win XP,R 2.12.0


你怎么看到内存没有被释放? - eyquem
@eyquem:只是使用任务管理器的图表和统计数据 :) - Benjamin
1个回答

7
在rpy文档中有一段提示,当删除或覆盖大型对象时,您可能需要经常运行Python垃圾回收器:rpy文档中的一个段落

R对象存在于R内存空间中,它们的大小对Python是未知的,因此似乎Python在涉及大型对象时并不总是进行足够的垃圾回收。这有时会导致在循环中覆盖大型对象时出现瞬态增加的内存使用量,尽管达到系统的内存限制似乎会触发垃圾回收,但我们可能希望显式地触发该集合。

我能够通过在创建矩阵后立即运行gc.collect(),然后在删除矩阵并运行R的内部gc()函数后再次运行来强制rpy2释放这个大矩阵。在循环中用睡眠运行它 - 使用top观察内存使用量的增加/减少。
在Ubuntu 10.0.4上使用Python 2.6,在python-rpy版本2.0.8与R版本2.10.1链接下运行。希望这可以帮助您取得一些进展。
import gc
import time

import rpy2.robjects as R

for i in range(5):
    print 'pass %d' % i
    R.r('a = matrix(NA, 1000000, 50)')
    gc.collect()
    R.r('rm(a)')
    R.r('gc()')
    gc.collect()

    print 'sleeping..'
    time.sleep(5)

那很有帮助,谢谢。然而,如果我在 IDLE 中逐行运行它,我需要运行 gc.collect() 多次才能使其正常工作。有什么想法为什么会这样? - Benjamin
我认为这与gc.collect()的作用有关,它会释放内存以供Python进程中的其他分配使用(将块返回到内部池),而不一定立即将其释放回操作系统。因此,多次调用collect可能会促使它更快地这样做。 - samplebias
2
如果我不给对象一个R名称,例如a = R.r('matrix(NA, 1000000, 50)'),那么这是否可能实现? - highBandWidth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接