由于您的代码,Python中是否可能发生实际的内存泄漏?

Orokusaki:

我没有代码示例,但我很好奇是否有可能编写导致本质上内存泄漏的Python代码。

崩溃:

有可能,是的。

这取决于您在谈论哪种内存泄漏。在纯python代码中,不可能像C语言那样“忘记释放”内存,但是有可能将引用悬挂在某个地方。这样的一些例子:

一个未处理的回溯对象,即使该函数不再运行,该对象仍可以使整个堆栈帧保持活动状态

while game.running():
    try:
        key_press = handle_input()
    except SomeException:
        etype, evalue, tb = sys.exc_info()
        # Do something with tb like inspecting or printing the traceback

在这个游戏循环的愚蠢示例中,我们为本地人分配了“ tb”。我们本来打算很好,但是此tb包含有关handle_input中一直发生的所有堆栈的帧信息,一直到此调用为止。假设您的游戏继续进行,则即使您下次调用handle_input时,此“ tb”仍会保留,甚至可能永远存在。现在,exc_info文档讨论了这个潜在的循环参考问题,并建议tb您在绝对不需要的情况下不要分配如果您需要回溯,请考虑例如traceback.format_exc

将值存储在类或全局范围而不是实例范围中,而不实现它。

这可能以阴险的方式发生,但是经常发生在您在类范围内定义可变类型时。

class Money(object):
    name = ''
    symbols = []   # This is the dangerous line here

    def set_name(self, name):
        self.name = name

    def add_symbol(self, symbol):
        self.symbols.append(symbol)

在上面的示例中,说您做了

m = Money()
m.set_name('Dollar')
m.add_symbol('$')

您可能会很快找到这个特定的错误,但是在这种情况下,您在类范围内放置了一个可变值,即使您在实例范围内正确访问了它,它实际上也“掉进了” 类对象__dict__

在某些情况下(例如持有对象),这可能会导致导致应用程序堆永久增长的事情,并可能导致生产Web应用程序偶尔不会重启进程的问题。

类中的循环引用也有一个__del__方法。

具有讽刺意味的是,a的存在__del__使循环垃圾收集器无法清理实例。假设您在某些地方想要做一个析构函数以用于最终确定:

class ClientConnection(...):
    def __del__(self):
        if self.socket is not None:
            self.socket.close()
            self.socket = None

现在,它本身就可以很好地工作,并且您可能会被认为会成为确保“处置”套接字的OS资源的好管家。

但是,如果ClientConnection保留了对引用的引用,User而User保留了对连接的引用,那么您可能会想说在清除时,让用户取消引用该连接。但是,这实际上是一个缺陷:循环GC不知道正确的操作顺序,因此无法清除它。

解决此问题的方法是确保您进行清理,例如通过调用某种close来断开事件,但是将该方法命名为而不是__del__

实现不好的C扩展,或者不能正确使用C库。

在Python中,您信任垃圾收集器丢弃不使用的东西。但是,如果您使用包装了C库的C扩展名,则大多数时候您要负责确保显式关闭或取消分配资源。大多数情况下,这已被记录在案,但是习惯于不必进行这种显式取消分配的python程序员可能会在不知道资源被占用的情况下,将句柄(例如从函数或其他东西返回)扔给该库。

包含闭包的作用域包含的数量超出了您的预期

class User:
    def set_profile(self, profile):
        def on_completed(result):
            if result.success:
                self.profile = profile

        self._db.execute(
            change={'profile': profile},
            on_complete=on_completed
        )

在这个人为的示例中,我们似乎正在使用某种“异步”调用,该调用将在on_completed完成DB调用时回叫我们(该实现本来是可以保证的,但最终会得到相同的结果)。

您可能没有意识到,on_completed闭包绑定了一个引用self以执行self.profile分配。现在,也许数据库客户端跟踪活动的查询和指向闭包完成时要调用的指针(因为它是异步的),并说它由于某种原因而崩溃。如果数据库客户端未正确清除回调等,则在这种情况下,数据库客户端现在具有对on_completed的引用,该引用具有对User的引用,该引用保留_db-您现在已经创建了一个可能永远不会被收集的循环引用。

(即使没有循环引用,闭包也会绑定本地变量,有时甚至是实例,这有时可能会导致您认为收集的值存在很长时间,其中可能包括套接字,客户端,大缓冲区和整个事物树)

可变类型的默认参数

def foo(a=[]):
    a.append(time.time())
    return a

这是一个人为的示例,但a实际上,它是对同一列表的引用时,可以认为默认值是一个空列表意味着要附加它这又可能会导致无限制的增长,而不知道您是否做到了。

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

通过FinalizerReference可能发生的内存泄漏

RabbitMQ QueueingConsumer可能发生内存泄漏

实际示例中的内存泄漏

此代码中是否存在内存泄漏?

评估树遍历递归算法(Java)中是否可能发生堆栈溢出错误

Java中潜在的内存泄漏,此代码可能导致内存泄漏吗?

lua代码中是否存在内存泄漏?(lua表)

服务工作者中是否可能发生自定义事件?

将活动上下文传递到静态方法中,是否可能发生内存泄漏?

以下代码是否可能发生内存泄漏?

Websharper应用程序中的性能降低,可能发生内存泄漏

Python3是否可以避免可能发生的DST更改?

QT Image Viewer示例,可能发生内存泄漏?

PM2-不正确的内存使用情况读取以及Node.js应用程序可能发生的内存泄漏

安全的Rust中是否可能发生不确定的行为?

R:删除ggplot2对象不会释放空间?可能发生内存泄漏?

在C ++中实现A *时可能发生内存泄漏

使用mplfinance / matplotlib时可能发生内存泄漏。怎么解决呢?

在仅基于交换机的网络中,是否可能发生数据包冲突?

CENTOS中可能发生的问题?

我的C ++文件中是否可能发生内存泄漏?

会话超时0:可能发生内存泄漏?

Qt:以下代码中是否存在内存泄漏?

这段代码中如何发生内存泄漏

以下C代码是否发生内存泄漏?

MediaElement在新媒体加载时是否可能发生内存泄漏?

星型拓扑交换机链路层中是否可能发生冲突?

iOS + Delphi:内存不足警告-TTexture可能发生内存泄漏?

使用指针算法进行迭代,是否可能发生内存泄漏?