“记忆泄漏”与问候?

时间:2012-08-05 10:20:49

标签: python gevent python-requests

这是脚本的精简版本,导致内存使用量不断增加,我看到它在2分钟后超过600MB:

import requests
import grequests

lines = (grequests.get(l.strip(), timeout=15) for l in open('links.txt') if len(l.strip()))

for r in grequests.imap(lines, size=20):
    if r.ok:
        print r.url

links.txt是一个包含大量网址的文件,问题出现在我收集的几个大网址组中。在我看来,响应对象可能没有被尊重?

我今天更新了gevent,请求和问候,这是他们的版本:

In [2]: gevent.version_info
Out[2]: (1, 0, 0, 'beta', 3)

In [5]: requests.__version__
Out[5]: '0.13.5'

grequests没有我能找到的版本号。

提前感谢您的任何答案。

3 个答案:

答案 0 :(得分:0)

从我的角度来看,这是因为你试图同时打开所有链接。尝试这样的事情:

links = set(links)
while links:
    calls = (grequests.get(links.pop()) for x in range(200)) 
    for r in calls:
        ...rest of your code

此代码未经过测试,您会发现更好的解决方案,这应该证明您同时尝试打开太多链接并导致您的内存消耗。

答案 1 :(得分:0)

这个答案只是一个别名,可以链接回可能需要此link的人。

我使用imap函数和requests.Session来减少内存使用量,同时在我的脚本中发出380k请求。

答案 2 :(得分:0)

应该更新项目的请求库依赖项。

较旧版本的请求(包括在问题示例中使用的版本)在默认情况下不会预取任何响应内容,由您自己来使用数据。这样就留下了对基础套接字的开放引用,因此,即使请求会话是垃圾回收的,在响应超出范围或调用response.content之前,也不会垃圾回收套接字。

在更高版本的请求中,默认情况下会预先提取响应,并且如果临时创建会话是为了满足模块级get / post / etc这样的请求,则会话将被明确关闭就像grequests在未传递会话时所做的一样。requests GitHub issue #520中对此进行了介绍。