【问题标题】:Object does not get deleted completely对象没有被完全删除
【发布时间】:2020-09-10 01:39:10
【问题描述】:

在我的代码中,我在 for 循环中创建了一个对象列表。像这样:(get_size 函数是从这里获得的:How do I determine the size of an object in Python?

def mem_now():
    mem = psutil.Process(os.getpid()).memory_info()
    mem = mem[0]/(1024.**2)
    return mem

class lista():
    def __init__(self, val):
        self.x = val
        self.y = val**2
        self.z = val - 1

intlst = []
objlst = []

for i in range(int(1e5)):
    g = lista(i)
    objlst.append(g)
    intlst.append(g.z)

print 'int_list_size = {:.2f} Mb'.format(get_size(intlst)/1e6)
print 'obj_list_size = {:.2f} Mb'.format(get_size(objlst)/1e6)

print 'mem_now (no del) = {:.2f} Mb'.format(mem_now())

del intlst

print 'mem_now (del int) = {:.2f} Mb'.format(mem_now())

del objlst

print 'mem_now (del obj) = {:.2f} Mb'.format(mem_now())

输出如下:

mem_now = 45.11 Mb

int_list_size = 3.22 Mb
obj_list_size = 43.22 Mb

mem_now (no del) = 103.35 Mb
mem_now (del int) = 103.35 Mb
mem_now (del obj) = 69.10 Mb

如您所见,删除列表后,我仍然没有清除所有内存。我运行的属性越多,迭代次数越多,最终的内存值就越大。我想完全删除我创建的所有对象,我该怎么做?

【问题讨论】:

  • 可以尝试导入python垃圾收集器import gc,然后手动调用收集,如gc.collect()
  • 感谢 Marco,但这并没有真正的帮助。在这个特定的例子中,它会将最后一个内存值减少到 68.07 Mb
  • 您不能在 Python 中手动删除对象。 del 不删除对象,它删除名称,即引用
  • @Marco 在这里不会有什么不同。 gc 只控制循环垃圾收集器,它负责循环引用,这里没有创建。 CPython使用引用计数,当引用计数达到0时,立即回收对象。
  • 即使您可以直接强制在 C 级别释放对象,操作系统可能仍然决定保留该内存为过程。 (实际上很有可能,只要没有其他进程需要内存)。更不用说可能涉及多层地址空间虚拟化。这在现代平台上完全超出了您的控制范围。

标签: python class object memory


【解决方案1】:

我想彻底删除我创建的所有对象,我该怎么做?

你做到了。你甚至不需要使用deldel 所做的只是删除一个 reference;当没有更多的引用时,底层的 object 会被清理它)。

考虑一个更简单的例子:

def alloc():
    global x
    x = list(range(1000000))

for i in range(1000):
    alloc()

我们在循环中从头开始重复创建列表。即使我们没有从之前的迭代中“删除”列表(您不需要,并且不应该尝试),我们也不会耗尽内存 - 因为清理是自动的。 (如果您确实内存不足,Python 会在分配失败时引发 MemoryError。)x 在我的系统上表示大约需要 36 兆字节(8 用于列表,28 用于整数);我没有 36 GB 的 RAM,但没有问题。只需要一点时间(在我的系统上大约需要 19 秒);内存使用量不会随着时间的推移而上升。

当我随后del x 时,在我的系统上,进程内存使用率(由任务管理器报告)立即下降。不过,事情是这样的:它可能不会始终如一地这样做,或者根本不会这样做,或者不会立即这样做,或者它可能取决于您使用什么工具来检查。这可能取决于您的操作系统和其他平台详细信息。无论如何,这不是你梦想完全用 Python 控制的东西,而且我怀疑很多时候你甚至无法从汇编中做到这一点。别担心。操作系统比你更清楚如何为进程分配内存。这就是为什么您的计算机有一个。

【讨论】:

    猜你喜欢
    • 2019-03-30
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 2015-11-27
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多