2

我继承的代码太嵌套,无法在这里尝试解释。基本上我定义了一个类方法,它复制复杂的图形结构(例如graph=NetworkX_graph.copy())并将其作为命名元组的一部分返回。

返回的命名元组与最大值进行比较,如果它更高,则保留它。例如

if value > max_value:
    best_value = {"index": index, "value": value, "graph": graph}

如何释放为我复制的对象分配的内存?!?我已经尝试了我能想到的一切。我目前正在使用memory_profiler并将 @profile 装饰器附加到包含 .copy() 的方法。我正在处理的测试用例中的那个副本以 7.8MB 为增量(根据情况可能会更高或更低)并且永远不会发布。它只是不断攀升,直到应用程序本身超过可用的系统内存并开始交换到磁盘。(丑陋...)

我尝试将不再需要的元组设置为 None,将其设置为“删除”,然后是 gc.collect() 和 gc.collect(2)。内存使用量不断增长。

顺便说一句,我坚持使用 Python 2.6,我可以强制迁移到 2.7。

可能是因为我正在使用元组吗?

4

1 回答 1

0

好的,我解决了。它需要一点重构。当我传入对象引用(作为方法/函数调用的参数)时,对该引用的任何更改都会导致分配新内存。在引用超出范围之前,内存不会被释放/gc.collect()。例如,代码指针返回到首先传递相关引用的函数/方法,并且该函数/方法退出。

以下是我试图说明问题的最多时间:

_compute(self, graph):
    maxValue = 5
    values = {}
    keeper = {}
    values ["graph"] = graph.copy()
    for i in range(1,1000):
        self._process(values )
        if values ["value"] > maxValue:
            keeper = {"graph":values ["graph"], "value":values ["value"]}

_process(self, values):
    graph = values["graph"]
    # Do some graph processing, like make a copy, allocate some memory, add some vertex values, etc... 
    values["value"] = <some value, like 0 to 10>
    values["graph"] = graph

对作为引用传递给 _process 的“值”对象的任何更改都将导致 Python 运行时保存更改数据的新旧版本。在您返回 _compute 并退出之前,它不会被释放。

我的解决方法是修改 _process 方法以实际返回图形对象。一旦我返回对象而不是修改传入的引用,垃圾收集就会返回以正确释放分配的内存。

_compute(self, graph):
    maxValue = 5
    values = {}
    keeper = {}
    values ["graph"] = graph.copy()
    for i in range(1,1000):
        newGraph = self._process(values )
        if values ["value"] > maxValue:
            keeper = {"graph":newGraph, "value":values ["value"]}

_process(self, values):
    graph = values["graph"]
    # Do some graph processing, like make a copy, allocate some memory, add some vertex values, etc... 
    values["value"] = <some value, like 0 to 10>
    return graph

我并不是说我的答案是最好的,或者我什至知道发生了什么,因为我不是 Python 专家,但希望这可以帮助像我一样寻找内存消耗线索的人。

于 2013-05-03T14:37:35.383 回答