如何在python函数调用后返回已用内存

时间:2016-05-08 21:48:30

标签: python memory-management

我正在尝试编写一个python模块,用于检查存储在HW内存中的mac地址的一致性。规模可以达到80K mac地址。但是当我通过python方法进行多次调用以获取mac地址列表时,内存不会被释放,最终我的内存不足。

我正在做的一个例子是:

import resource
import copy


def get_list():
    list1 = None
    list1 = []
    for j in range(1,10):
        for i in range(0,1000000):
            list1.append('abcdefg')
        print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000)
    return list1

for i in range(0,5):
    x=get_list()

在执行脚本时,我得到:

45805
53805
61804
69804
77803
85803
93802
101801
109805
118075
126074
134074
142073
150073
158072
166072
174071
182075
190361
198361
206360
214360
222359
230359
238358
246358
254361
262365
270364
278364
286363
294363
302362
310362
318361
326365
334368
342368
350367
358367
366366
374366
382365
390365
398368

即。报告的内存使用量持续上升。 我是以错误的方式查看内存使用情况吗? 如果没有,有没有办法在循环中的函数调用之间没有内存使用量。 (在我的情况下使用mac地址,我不会再次调用相同的mac地址列表。我从HW内存的不同部分获取列表。即获取mac地址的所有调用都是有效的,但是在每次调用数据之后获得的是无用的,可以丢弃。

2 个答案:

答案 0 :(得分:1)

Python是一种托管语言。一般来说,内存是实现的关注点,而不是普通的开发人员。该系统旨在回收您不再自动使用的内存。

如果您正在使用CPython,则当引用计数达到零时,或者当循环垃圾收集器找到并收集它时,将销毁该对象。如果要回收属于某个对象的内存,则需要确保不保留对它的引用,或者至少从任何堆栈框架的变量都无法访问它。也就是说,不应该直接或通过某些表达式(例如foo.bar[42])从任何当前正在执行的函数中引用要回收的数据。

如果您正在使用其他实现,例如PyPy,则规则可能会有所不同。特别是,Python语言标准不需要引用计数,因此在下一次垃圾收集运行之前对象可能不会消失(然后您可能必须等待收集正确的generation)。

对于旧版本的Python(在Python 3.4之前),您还需要担心涉及终结器(__del__()方法)的引用周期。旧的垃圾收集器无法收集这样的周期,因此它们(基本上)get leaked。大多数内置类型没有终结器,无法参与参考周期,或者两者兼而有之,但如果您要创建自己的类,这是一个合理的问题。

对于您的用例,当您不再需要其内容时(例如list1 = []del list1[:]),您应该清空或替换列表,或者从创建它的函数返回(假设它是局部变量,而不是全局变量或其他一些这样的东西)。如果您发现之后内存仍然不足,则应切换到较低开销的语言(如C)或投入更多内存。对于更复杂的情况,您可以使用gc module来测试和评估垃圾收集器如何与您的程序进行交互。

答案 1 :(得分:0)

试试这个:它可能不会释放内存,因为它可能仍在使用中。 看看它是否有效

gc.collect()