Eug*_*gen 0 python python-requests
当使用请求库检索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
Run Code Online (Sandbox Code Playgroud)
以下是我在解释器中得到的输出。
>>> 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'
Run Code Online (Sandbox Code Playgroud)
显然,我不应该尝试将pdf文件解码为文本。但是,这种行为的原因到底是什么?
当没有charset参数被包括在内容类型和响应是不是一个text/MIME类型,则一个字符检测库被用来确定编解码器。
通过使用response.text您触发此检测,加载了库,并且它的模块包括一些可伸缩的表。
根据所安装的确切版本requests,您会发现sys.modules['requests.packages.chardet']或sys.modules['requests.packages.charade']存在该版本,以及大约36个子模块,而这些子模块在您使用之前就没有r.text。
随着检测的进行,会创建许多对象,这些对象使用PDF文档上的各种统计技术,因为检测无法足够确定地命中任何特定的编解码器。为了将所有这些存储在内存中,Python要求从您的OS中分配更多的内存。一旦检测过程完成后,内存再次释放,但OS的确不是那么取消分配内存,而不是马上。这样做是为了防止野生内存搅动,因为进程可以轻松地请求并按周期释放内存。
请注意,您还添加了的结果r.text到您的内存中,绑定到t。这是一个Unicode文本对象,在Python 2中占用的内存是字节串对象的2到4倍。您所拥有的特定下载字节串将近4 MB,但是如果您使用的是UCS-4 Python构建,那么所得的Unicode值将为解码后的值再加上16 MB 。
| 归档时间: |
|
| 查看次数: |
2780 次 |
| 最近记录: |