首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何找出扭曲服务器内存使用量增加的原因?

如何找出扭曲服务器内存使用量增加的原因?
EN

Stack Overflow用户
提问于 2010-01-20 17:18:31
回答 3查看 2.7K关注 0票数 17

我有一个用Python编写的音频广播服务器,基于Twisted。它工作得很好,但当服务器上有更多用户时,它的内存使用率会增加,但当这些用户脱机时,内存使用率永远不会下降。如下图所示:

您可以看到内存使用率曲线在侦听器/无线电的曲线上升时上升,但在侦听器/无线电的峰值之后,内存使用率仍然很高,永远不会下降。

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

  1. 升级从8.2到9.0
  2. 使用guppy转储heapy,但在
  3. 将选择器反应器切换到epoll反应器时完全没有帮助,同样的问题。
  4. 使用objgraph绘制对象关系图,但我看不到其中的要点。

<代码>G210

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

Red: 2.5.4 r254:67916

  • OS: 4.1.2-46))

  • Twisted: 2.6.18-164.9.1.el5PAE (
  • mockbuild@builder16.centos.org)(红帽Python 4.1.2 20080704 (Red 9.0 (在virtualenv下)

孔雀鱼的垃圾堆:

代码语言:javascript
复制
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命令报告的

代码语言:javascript
复制
[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的隐形内存使用量,它们是什么?

我的问题是:

  1. 如何找到内存使用率增加的原因?
  2. 对于guppy来说,什么是可见的内存使用率?
  3. 那些不可见的内存使用率是什么?
  4. 是由C编写的一些模块的内存泄漏引起的吗?如果是,我如何跟踪和修复它?
  5. 如何管理内存?内存池?我认为这可能是由音频数据块引起的。因此Python interpreter.

拥有的内存块中几乎没有泄漏

Update2010/1/20:很有趣,我下载了最新的日志文件,它显示内存永远不会随着时间的推移而增加。我认为可能是分配的内存空间足够大。这是最新的数据。

更新2010/1/21:另一个数字在这里。嗯..。再提高一点

哦..。还在往上走

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-02-09 20:40:00

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

  1. 区块大小511
  2. 区块大小1040
  3. 区块大小386
  4. 区块大小1350
  5. ...

其中大多数大于256字节,Python对大于256字节的块使用malloc,而不是使用内存池。你可以想象,如果这些块被分配和释放,会发生什么?例如,当释放大小为1350的块时,堆中可能有1350字节的空闲空间。在那之后,这里是另一个请求988,一旦malloc拿起了这个洞,然后就有另一个大小为362的新的小空洞。经过长时间的运行,堆中的小洞越来越多,换句话说,堆中有太多的碎片。虚拟内存的页面大小通常为4KB,这些碎片分布在一个很大的堆范围内,这使得操作系统无法将这些页面换出。因此,RSS总是很高。

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

新的设计使用bytearray而不是list of strings。它是一个很大的内存块,所以没有更多的碎片。

票数 6
EN

Stack Overflow用户

发布于 2010-01-20 19:17:21

对我来说,这听起来确实像是C模块中的内存泄漏。Valgrind是跟踪内存分配相关问题的一个很好的工具。不过,我不知道它在运行时加载的模块上有多好。

票数 2
EN

Stack Overflow用户

发布于 2010-01-20 19:03:45

你有没有想过用CentOS的方式来替代dtrace - SystemTap,我想它叫做。

这应该会让你对你的*nix进程内部发生的事情有一个相当低层次的跟踪......……暗算一下,但可能会让你对进程内的活动有更多的透明度。

不过,这个问题很有趣。期待看到其他人的回应。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2100192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档