在Python中释放内存

贾里德:

在以下示例中,我有一些有关内存使用的相关问题。

  1. 如果我在解释器中运行,

    foo = ['bar' for _ in xrange(10000000)]
    

    我的机器上使用的实际内存最高为80.9mb那我

    del foo
    

    实际内存下降,但仅限于30.4mb解释器使用4.4mb基线,因此不26mb向OS 释放内存有什么好处是因为Python在“提前计划”,以为您可能会再次使用那么多的内存吗?

  2. 它为什么50.5mb特别释放- 释放的量基于什么?

  3. 有没有一种方法可以强制Python释放所有已使用的内存(如果您知道不会再使用那么多的内存)?

注意此问题不同于我如何在Python中显式释放内存?因为这个问题主要解决了内存使用量相对于基线的增加,即使在解释器通过垃圾回收(使用gc.collect或不使用释放对象之后也是如此。

孙ry

堆上分配的内存可能会出现高水位标记。Python的内部优化PyObject_Malloc在4个KiB池中分配小对象()的情况非常复杂,分类的分配大小是8字节的倍数-最多256字节(3.3中为512字节)。池本身位于256 KiB竞技场中,因此,如果仅在一个池中使用一个块,则不会释放整个256 KiB竞技场。在Python 3.3中,小对象分配器已切换为使用匿名内存映射而不是堆,因此它在释放内存方面应表现更好。

此外,内置类型维护先前分配对象的空闲列表,这些对象可能使用也可能不使用小型对象分配器。int类型会维护一个具有自己分配的内存的空闲列表,要清除它,需要调用PyInt_ClearFreeList()这可以通过做一个full来间接调用gc.collect

这样尝试,然后告诉我您得到了什么。这是psutil.Process.memory_info的链接

import os
import gc
import psutil

proc = psutil.Process(os.getpid())
gc.collect()
mem0 = proc.get_memory_info().rss

# create approx. 10**7 int objects and pointers
foo = ['abc' for x in range(10**7)]
mem1 = proc.get_memory_info().rss

# unreference, including x == 9999999
del foo, x
mem2 = proc.get_memory_info().rss

# collect() calls PyInt_ClearFreeList()
# or use ctypes: pythonapi.PyInt_ClearFreeList()
gc.collect()
mem3 = proc.get_memory_info().rss

pd = lambda x2, x1: 100.0 * (x2 - x1) / mem0
print "Allocation: %0.2f%%" % pd(mem1, mem0)
print "Unreference: %0.2f%%" % pd(mem2, mem1)
print "Collect: %0.2f%%" % pd(mem3, mem2)
print "Overall: %0.2f%%" % pd(mem3, mem0)

输出:

Allocation: 3034.36%
Unreference: -752.39%
Collect: -2279.74%
Overall: 2.23%

编辑:

我改用相对于进程VM大小的度量来消除系统中其他进程的影响。

当顶部的连续可用空间达到恒定,动态或可配置的阈值时,C运行时(例如glibc,msvcrt)会缩小堆。使用glibc,您可以使用mallopt(M_TRIM_THRESHOLD)进行调整。鉴于此,如果堆的收缩量比您的块收缩的量更大,甚至更多,也就不足为奇了free

在3.x range中,不会创建列表,因此上面的测试不会创建1000万个int对象。即使这样做,int3.x中类型也基本上是2.x long,它没有实现自由列表。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章