在保留所有表单实例的引用时,django中的内存泄漏

时间:2013-12-27 10:30:58

标签: python django memory-leaks metaprogramming

这是this thread的后续内容。

我已经实现了一个方法来保持对数组中所有表单的引用,就像所选答案所提到的一样,但遗憾的是我在每次请求django主机时都会出现内存泄漏。

有问题的代码如下:

这是我扩展的自定义表单,它具有保留相邻表单引用的功能,每当我实例化一个新表单时,它就会不断添加到_instances堆栈。

class StepForm(ModelForm):
    TAGS = []
    _instances = []

    def __new__(cls, *args, **kwargs):
        instance = object.__new__(cls)
        cls._instances.append(instance)
        return instance

即使这是一个python问题,然后Django我已经决定最好向你展示我遇到这个问题的完整背景。

根据要求,我发布了我想要用这个专长完成的任务:

我有一个带步骤的js applet,并且每个步骤都有一个表单,但是为了通过JS动态加载每个步骤的内容,我需要在下一个表单上执行一些调用。而在以前也是如此。因此,我能想到的唯一解决方案是在每个请求上保留对所有表单的引用,并使用我需要的表单函数。

2 个答案:

答案 0 :(得分:2)

这不仅是一个Python问题 - 执行上下文(这里是一个Django应用程序)也很重要。正如Ludwik Trammer正确评论的那样,你处于一个漫长的过程中,因此在模块或类级别的任何事情都将在整个过程中存在。此外,如果使用多个进程来为应用程序提供服务,您可能(并且将)从一个请求到另一个请求获得不一致的结果,因为来自同一用户的两个后续请求可能(并且将)最终由不同进程提供服务。

简而言之:在Web应用程序中安全地保持每用户持久状态的方法是使用会话。请解释一下您要解决的问题,很可能是一个更合适的(可能是现有的和经过测试的)解决方案。

编辑:好的,你正在寻找的是一个“巫师”。 Django有几个可用的实现,但是大多数都不能处理 - 从经验来看,当每个步骤依赖于前一个步骤时(这是使用向导的驱动点之一)可能会变得棘手。通常做的是有一个带有一组表单的`Wizard'类(普通的旧Python对象)。

向导负责

  1. 步骤导航
  2. 实施表格
  3. 维护状态(包括存储和检索每个步骤的表单数据,重新验证等)。
  4. FWIW我使用Django现有的基于会话的向导取得了相当大的成功。我们为另一个项目(有些复杂的要求)推出了自己的项目,虽然它有效但我也不认为它成功。在混合中抛出ajax和文件上传也无济于事。无论如何,你可以尝试从现有的实现开始,看看它是如何满足你的需求的,如果没有,那么就去寻找一个自定义的解决方案 - 通用的解决方案有时会使事情变得比以前更难。

    我的2美分......

答案 1 :(得分:1)

泄漏不只是代码的副作用 - 它是核心功能的一部分。如果不改变代码的作用,就无法删除泄漏。

完全它被编程的内容 - 每个时间表单显示一个新实例被创建并添加到_instances列表中。永远不会从列表中删除它。因此,在100个请求之后,您将有一个包含100个请求的列表,在1 000个请求之后,列表中将有1 000个实例,依此类推 - 直到所有内存都耗尽并且程序崩溃。

通过保留表单的所有实例,您想要完成什么?你还期望发生什么?