FreeBSD上的Python字符串内存使用情况
我在使用FreeBSD的 python字符串观察一个奇怪的内存使用模式。考虑 下面的会议。想法是创建一个列表,其中包含一些 字符串,以便列表中的累积字符为100MB。FreeBSD上的Python字符串内存使用情况
l = []
for i in xrange(100000):
l.append(str(i) * (1000/len(str(i))))
这个使用了大约100MB的内存,'del l'会清除它。
l = []
for i in xrange(20000):
l.append(str(i) * (5000/len(str(i))))
这是使用165MB的内存。我真的不明白 额外的内存使用来自何处。 [两个列表的大小相同]
FreeBSD上的Python 2.6.4 7.2。在Linux/windows上都使用 只有100MB内存。
更新:我使用'ps aux'测量内存。这可以在上面的代码片段之后使用os.sytem来执行。这些也分开执行。
Update2:看起来像freebsd mallocs内存的倍数为2.因此分配5KB实际上分配8KB。虽然我不确定。
在我看来,这可能是记忆中的碎片。首先,大于255字节的内存块将在CPython中分配malloc。您可以参考
Improving Python's Memory Allocator
出于性能方面的原因,大多数的内存分配,malloc之类,会返回一个对齐的地址。例如,你永远不会得到像
0x00003
它没有对齐4个字节,它将是非常缓慢的计算机访问内存。因此,您通过malloc获得的所有地址应该是
0x00000
0x00004
0x00008
等等。 4字节对齐只是基本的通用规则,对齐的真正策略是OS变体。
你所说的内存使用应该是RSS(不确定)。对于大多数操作系统,虚拟内存的页面大小为4K。对于你分配的内容,你需要2页来存储5000字节的块。让我们看一个例子来说明一些内存泄漏。我们假设这里的对齐是256字节。
0x00000 {
... chunk 1
0x01388 }
0x01389 {
... fragment 1
0x013FF }
0x01400 {
... chunk 2
0x02788 }
0x02789 {
... fragment 2
0x027FF }
0x02800 {
... chunk 3
0x03B88 }
0x03B89 {
... fragment 3
0x04000 }
正如你可以看到有在内存中,因此许多碎片,它们不能用了,不过,他们占据了页面的存储空间。我不确定FreeBSD的对齐策略是什么,但我认为这是由于这样的原因造成的。为了使用Python高效地使用内存,你可以使用预先分配好的大块数据块bytearray,并选择一个好数字作为要使用的块(你必须测试以确定哪个数字最好,这取决于OS)。
什么第一执行第二一段代码然后执行第一个?我再次考虑它将是165 MB,因为这涉及操作系统/ python解释器和垃圾回收器如何管理内存。 – Hossein 2011-03-17 17:14:54
你如何确定它使用的内存?你确定它是正确的吗? – steabert 2011-03-17 17:28:32