【问题标题】:Releasing memory in python script在 python 脚本中释放内存
【发布时间】:2016-05-22 10:44:11
【问题描述】:

我有一个可以抓取一些 url 的 python 脚本。我有一个 url 列表,对于每个 url,我得到 html 并用它做一些逻辑。

我使用 Python 2.7.6 和 Linux Mint 17 Cinnamon 64 位。

问题是我的主要抓取对象(我为每个 url 实例化)从未从内存中释放,尽管没有引用它。由于这个问题,我的内存一直在快速增长(因为我的对象有时非常大 - 高达 50MB)。

简化代码如下所示:

def scrape_url(url):
    """
    Simple helper method for scraping url
    :param url: url for scraping
    :return: some result
    """
    scraper = Scraper(url)  # instance main Scrape object
    result = scraper.scrape()  # scrape it

    return result

## SCRIPT STARTS HERE
urls = get_urls()  # fetch some list of urls

for url in urls:
    print 'MEMORY USAGE BEFORE SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    result = scrape_url(url)  # call helper method for scraping
    print 'MEMORY USAGE AFTER SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    print '-' * 50

我的输出是这样的:

MEMORY USAGE BEFORE SCRAPE: 75732 (kb)
MEMORY USAGE AFTER SCRAPE: 137392 (kb)
--------------------------------------------------
MEMORY USAGE BEFORE SCRAPE: 137392 (kb)
MEMORY USAGE AFTER SCRAPE: 206748 (kb)
--------------------------------------------------
MEMORY USAGE BEFORE SCRAPE: 206748 (kb)
MEMORY USAGE AFTER SCRAPE: 284348 (kb)
--------------------------------------------------

Scrape 对象很大,它没有从内存中释放。 我试过了:

scraper = None

del scraper

甚至调用 gc 来收集对象:

gc.collect()

但没有任何帮助。

当我打印对刮板对象的引用数量时:

print sys.getrefcount(scraper)

我得到 2,我认为这意味着没有其他对对象的引用,应该由 gc 清理。

Scraper 对象有很多子对象。是否有可能其中一些子对象的引用被留在某处,因此 gc 无法释放主 Scaper 对象,或者还有其他原因导致 python 不释放内存?

我在 SO 中找到了一些与此相关的主题,以及他们所说的一些响应,即除非您生成/杀死子进程,否则无法释放内存,这听起来很奇怪 (LINK)

谢谢, 伊万

【问题讨论】:

  • "Scraper 对象有很多子对象...不释放内存?"这将是唯一合理的理由。抓取网址在我假设的端口上建立了连接?可能该连接具有常设参考。
  • 你确定这个结果和scraper没有关联吗?

标签: python memory memory-leaks garbage-collection


【解决方案1】:

您正在使用一个迭代器,它必须始终在内存中。 重写你的循环以使用生成器并懒惰地刮。大致如下:

def gen():
        for i in xrange(0, len(urls)):
            yield urls[i]

【讨论】:

  • 或带有 gen=(url for url in urls) 的生成器表达式
猜你喜欢
  • 2017-09-08
  • 2013-03-05
  • 2016-09-03
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 2010-11-16
  • 2023-04-05
相关资源
最近更新 更多