2011-03-17 61 views
6

我在使用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。虽然我不确定。

+0

什么第一执行第二一段代码然后执行第一个?我再次考虑它将是165 MB,因为这涉及操作系统/ python解释器和垃圾回收器如何管理内存。 – Hossein 2011-03-17 17:14:54

+5

你如何确定它使用的内存?你确定它是正确的吗? – steabert 2011-03-17 17:28:32

回答

0

答案可能在this saga。我认为你正在目睹一些不可避免的内存管理器开销。

正如@Hossein所说,尝试在一次运行中执行两个代码片段,然后交换它们。

1

在我看来,这可能是记忆中的碎片。首先,大于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)。

0

我认为freebsd中的所有内存地址都必须与两个幂对齐。因此,所有python的内存池都有点碎片化到内存中,而不是连续的。

尝试使用一些其他tool被发现什么有趣