我有一个用Python编写的音频广播服务器,基于Twisted。它工作得很好,但当服务器上有更多用户时,它的内存使用率会增加,但当这些用户脱机时,内存使用率永远不会下降。如下图所示:
您可以看到内存使用率曲线在侦听器/无线电的曲线上升时上升,但在侦听器/无线电的峰值之后,内存使用率仍然很高,永远不会下降。
我尝试了以下方法来解决这个问题:
<代码>G210
下面是我用来运行我的扭曲服务器的环境:
Red: 2.5.4 r254:67916
孔雀鱼的垃圾堆:
Partition of a set of 116280 objects. Total size = 9552004 bytes.
Index Count % Size % Cumulative % Type
0 52874 45 4505404 47 4505404 47 str
1 5927 5 2231096 23 6736500 71 dict
2 29215 25 1099676 12 7836176 82 tuple
3 7503 6 510204 5 8346380 87 types.CodeType
4 7625 7 427000 4 8773380 92 function
5 672 1 292968 3 9066348 95 type
6 866 1 82176 1 9148524 96 list
7 1796 2 71840 1 9220364 97 __builtin__.weakref
8 1140 1 41040 0 9261404 97 __builtin__.wrapper_descriptor
9 2603 2 31236 0 9292640 97 int
如您所见,总大小为9552004字节的RSS9.1MB,您可以看到ps命令报告的:
[xxxx@webxx ~]$ ps -u xxxx-o pid,rss,cmd
PID RSS CMD
22123 67492 twistd -y broadcast.tac -r epoll
我的服务器的rss是65.9MB,这意味着我的服务器中有56.8MB的隐形内存使用量,它们是什么?
我的问题是:
拥有的内存块中几乎没有泄漏
Update2010/1/20:很有趣,我下载了最新的日志文件,它显示内存永远不会随着时间的推移而增加。我认为可能是分配的内存空间足够大。这是最新的数据。
更新2010/1/21:另一个数字在这里。嗯..。再提高一点
哦..。还在往上走
发布于 2010-02-09 20:40:00
据我猜测,这是由于内存碎片问题。最初的设计是将音频数据块保存在一个列表中,它们都不是固定大小的。一旦缓冲列表的总大小超过了缓冲区的限制,它就会从列表的顶部弹出一些块来限制大小。它可能看起来像这样:
其中大多数大于256字节,Python对大于256字节的块使用malloc,而不是使用内存池。你可以想象,如果这些块被分配和释放,会发生什么?例如,当释放大小为1350的块时,堆中可能有1350字节的空闲空间。在那之后,这里是另一个请求988,一旦malloc拿起了这个洞,然后就有另一个大小为362的新的小空洞。经过长时间的运行,堆中的小洞越来越多,换句话说,堆中有太多的碎片。虚拟内存的页面大小通常为4KB,这些碎片分布在一个很大的堆范围内,这使得操作系统无法将这些页面换出。因此,RSS总是很高。
在修改了我的服务器的音频块管理模块的设计后,它现在占用了很少的内存。您可以看到该图,并将其与前一个图进行比较。
新的设计使用bytearray而不是list of strings。它是一个很大的内存块,所以没有更多的碎片。
发布于 2010-01-20 19:17:21
对我来说,这听起来确实像是C模块中的内存泄漏。Valgrind是跟踪内存分配相关问题的一个很好的工具。不过,我不知道它在运行时加载的模块上有多好。
发布于 2010-01-20 19:03:45
你有没有想过用CentOS的方式来替代dtrace - SystemTap,我想它叫做。
这应该会让你对你的*nix进程内部发生的事情有一个相当低层次的跟踪......……暗算一下,但可能会让你对进程内的活动有更多的透明度。
不过,这个问题很有趣。期待看到其他人的回应。
本
https://stackoverflow.com/questions/2100192
复制相似问题