FreeBSD 上的 Python 字符串内存使用情况

标签 python malloc freebsd

我观察到一个奇怪的内存使用模式,其中包含 python 字符串 Freebsd。考虑 下届 session 。想法是创建一个列表,其中包含一些 字符串,以便列表中的累积字符为 100MB。

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 7.2 上的 Python 2.6.4。在 Linux/windows 上都使用 around 仅 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 字节对齐只是基本的通用规则,真正的对齐策略是操作系统变体。

而你说的内存占用应该是RSS(不确定)。对于大多数操作系统,虚拟内存的页面大小为 4K。对于您分配的内容,您需要 2 页来存储 5000 字节的 block 。让我们看一个示例来说明一些内存泄漏。我们假设此处对齐为 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 ,然后选择一个好的数字作为要使用的 block (您必须测试才能知道哪个数字最好,这取决于操作系统)。

关于FreeBSD 上的 Python 字符串内存使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5342600/

相关文章:

python - 如何避免爬虫中的重复

python - 什么时候 os.environ ['foo' ] 不匹配 os.getenv ('foo' )?

c++ - 如何使用 C 从 FreeBSD 获取 kenv 设置

c - 为什么在我有 16 GB RAM 的计算机上只能分配 2 GB?

c - 指向结构体的指针的二维数组(动态)

c - realloc 似乎没有重新分配内存

c - 简单分配中的段错误(核心转储)

python - Pandas:响应更快的语法或函数,将列中单元格的值与前一个单元格和其他列进行比较

python - f_oneway 当数据为列表形式时

python - 如何使用python从mysql数据库中删除