Asi*_*man 10 python solr memory-leaks
我在使用python脚本发出大型solr查询时遇到了一些内存问题.我正在使用solrpy库与solr服务器进行交互.该查询返回大约80,000条记录.发出查询后立即通过顶部气球查看到的python内存占用量为~190MB.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8225 root 16 0 193m 189m 3272 S 0.0 11.2 0:11.31 python
...
Run Code Online (Sandbox Code Playgroud)
此时,通过heapy查看的堆配置文件如下所示:
Partition of a set of 163934 objects. Total size = 14157888 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 80472 49 7401384 52 7401384 52 unicode
1 44923 27 3315928 23 10717312 76 str
...
Run Code Online (Sandbox Code Playgroud)
unicode对象表示查询中记录的唯一标识符.需要注意的一点是,总堆大小只有14MB,而python占用190MB的物理内存.一旦存储查询结果的变量超出范围,堆配置文件就会正确反映垃圾收集:
Partition of a set of 83586 objects. Total size = 6437744 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 44928 54 3316108 52 3316108 52 str
Run Code Online (Sandbox Code Playgroud)
但是,内存占用量保持不变:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8225 root 16 0 195m 192m 3432 S 0.0 11.3 0:13.46 python
...
Run Code Online (Sandbox Code Playgroud)
为什么python的物理内存占用与python堆的大小之间存在如此大的差异?
Python从C堆中分配Unicode对象.所以当你分配它们中的许多(以及其他malloc块),然后释放它们中的大部分除了最后一个,C malloc将不会向操作系统返回任何内存,因为C堆只会在最后收缩(不在中间).释放最后一个Unicode对象将释放C堆末尾的块,然后允许malloc将其全部返回给系统.
除了这些问题之外,Python还维护一个释放的unicode对象池,以便更快地进行分配.因此,当释放最后一个Unicode对象时,它不会立即返回到malloc,从而使所有其他页面都被卡住.