当前位置:  开发笔记 > 编程语言 > 正文

如何找到增加扭曲服务器内存使用量的来源?

如何解决《如何找到增加扭曲服务器内存使用量的来源?》经验,为你挑选了1个好方法。

我有一个用Python编写并基于Twisted的音频广播服务器.它工作正常,但当服务器上有更多用户时,其内存使用量会增加,但当这些用户下线时,内存使用量不会下降.如下图所示: alt text http://static.ez2learn.com/temp/mem_figure3.svg

你可以看到内存使用曲线在听众/收音机的曲线上升的地方上升,但是在收听者/收音机的峰值之后,内存使用量仍然很高,永远不会下降.

我试过以下方法来解决这个问题:

    升级扭曲从8.2到9.0

    使用孔雀鱼转储堆积,但根本没有帮助

    将选择器反应器切换到epoll反应器,同样的问题.

    使用objgraph绘制对象关系图,但我无法从中看到点.

这是我用来运行我的扭曲服务器的环境:

Python:2.5.4 r254:67916

操作系统:Linux版本2.6.18-164.9.1.el5PAE(mockbuild@builder16.centos.org)(gcc版本4.1.2 20080704(Red Hat 4.1.2-46))

扭曲:9.0(在virtualenv下)

孔雀鱼转储:

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字节为9.1 MB,您可以看到ps命令报告的rss:

[xxxx@webxx ~]$ ps -u xxxx-o pid,rss,cmd
  PID   RSS CMD
22123 67492 twistd -y broadcast.tac -r epoll

我的服务器的rss是65.9 MB,这意味着我的服务器中有56.8 MB的隐形内存使用量,它们是什么?

我的问题是:

    如何找到增加内存使用量的来源?

    孔雀鱼的可见内存使用量是多少?

    那些看不见的内存使用是什么?

    这是由用C编写的一些模块的内存泄漏引起的吗?如果是,我该如何追踪并修复它?

    Python如何管理内存?内存池?我认为这可能是由音频数据块引起的.因此Python解释器拥有的内存块几乎没有泄漏.

更新2010/1/20:有趣的是,我下载了最新的日志文件,它表明内存永远不会增加.我想可能是分配的内存空间足够大.这是最新的数字. alt text http://static.ez2learn.com/temp/mem_figure4.svg

更新2010/1/21:这里的另一个数字.哼......提高一点点 alt文本http://static.ez2learn.com/temp/mem_figure6.svg

哎呀...还在上面的 文字http://static.ez2learn.com/temp/mem_figure7.svg



1> Fang-Pen Lin..:

正如我的猜测,这是由于内存碎片问题.最初的设计是将音频数据块保存在列表中,所有这些块都不是固定大小的.一旦缓冲列表的总大小超过缓冲区的限制,它就会从列表顶部弹出一些块来限制大小.它可能看起来像这样:

    块大小511

    块大小1040

    块大小386

    块大小1350

    ...

其中大多数都大于256字节,Python使用malloc来处理大于256字节的块而不是使用内存池.你可以想象那些块被分配并释放,会发生什么?例如,当释放1350大小的块时,堆中可能有一个空闲的1350字节空间.在那之后,又来了另一个请求988,一旦malloc拿起洞,然后还有另一个362号的新小洞.经过长时间的运行,堆中有越来越多的小洞,换句话说,就是这样堆中的许多碎片.虚拟内存的页面大小通常是4KB,那些片段分布在很大的堆栈范围内,这使得OS无法交换那些页面.因此,RSS始终很高.

在修改了我的服务器的音频块管理模块的设计之后,它现在使用很少的内存.您可以看到该图并与之前的图进行比较.

alt text http://static.ez2learn.com/temp/new_mem_figure.svg

新设计使用bytearray而不是字符串列表.它是一大块内存,所以没有更多的碎片.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有