我注意到使用请求库检索pdf文件时内存使用量大幅增加。文件本身大约4MB,但分配给python进程的物理内存增加了超过150MB!
有人知道这种行为的可能原因(也许是修复)吗?
这是测试用例:
import requests,gc
def dump_mem():
s = open("/proc/self/status").readlines()
for line in s:
if line.startswith("VmRSS"):
return line
以下是我在intrepretter中得到的输出。
>>> gc.collect()
0
>>> dump_mem()
'VmRSS:\t 13772 kB\n'
>>> gc.collect()
0
>>> r = requests.get('http://www.ipd.uni-karlsruhe.de/~ovid/Seminare/DWSS05/Ausarbeitungen/Seminar-DWSS05')
>>> gc.collect()
5
>>> dump_mem()
'VmRSS:\t 20620 kB\n'
>>> r.headers['content-length']
'4089190'
>>> dump_mem()
'VmRSS:\t 20628 kB\n'
>>> gc.collect()
0
>>> c = r.content
>>> dump_mem()
'VmRSS:\t 20628 kB\n'
>>> gc.collect()
0
>>> t = r.text
>>> gc.collect()
8
>>> dump_mem()
'VmRSS:\t 182368 kB\n'
显然,我不应该尝试将pdf文件解码为文本。但无论如何,这种行为的原因是什么?
答案 0 :(得分:3)
如果内容类型中不包含charset
参数且响应不 text/
mimetype,则使用字符检测库来确定编解码器。< / p>
使用response.text
触发了这个检测,加载了库,它的模块包含了一些相当大的表。
根据您已安装的requests
的确切版本,您会发现现在有sys.modules['requests.packages.chardet']
或sys.modules['requests.packages.charade']
以及大约36个子模块,在你使用r.text
之前。
当检测运行时,会创建许多在PDF文档中使用各种统计技术的对象,因为检测无法在任何特定编解码器上获得足够的确定性。为了使所有这些适合内存,Python要求从您的操作系统分配更多内存。一旦检测过程完成,该内存将再次释放,但操作系统不然后取消分配该内存,而不是立即取消分配。这样做是为了防止疯狂的内存流失,因为进程可以轻松地请求并释放内存。
请注意,您还将r.text
的结果添加到您的记忆中,并绑定到t
。这是一个Unicode文本对象,在Python 2中占用的内存是bytestring对象的2到4倍。您在那里的特定下载将近4 MB作为字节字符串,但如果您使用的是UCS-4 Python构建,则生成的Unicode值仅为解码值添加另外16 MB 。