4

我有一个包含大约 30k 记录的表,我正在尝试使用 Django 的 ORM 对其进行迭代和处理。每条记录都存储几个二进制 blob,每个二进制 blob 的大小都可以是几 MB,我需要处理这些二进制 blob 并将其写入文件。

但是,由于内存限制,我在使用 Django 时遇到了麻烦。我的系统上有 8GB 内存,但在处理了大约 5k 条记录后,Python 进程消耗了全部 8GB 内存并被 Linux 内核杀死。我尝试了各种技巧来清除 Django 的查询缓存,例如:

  1. 定期调用MyModel.objects.update()
  2. 环境settings.DEBUG=False
  3. 通过定期调用 Python 的垃圾收集器gc.collect()

然而,这些似乎都没有任何明显的影响,我的进程继续经历某种内存泄漏,直到它崩溃。

还有什么我可以做的吗?

由于我一次只需要处理一条记录,并且在此过程中我不需要再次访问同一条记录,因此我不需要保存任何模型实例,或者一次加载多个实例。您如何确保只加载一条记录并且 Django 不缓存任何内容并在使用后立即取消分配所有内存?

4

1 回答 1

8

尝试使用迭代器。

QuerySet 通常在内部缓存其结果,以便重复评估不会导致额外的查询。相比之下,iterator() 将直接读取结果,而无需在 QuerySet 级别进行任何缓存(在内部,默认迭代器调用 iterator() 并缓存返回值)。对于返回大量只需要访问一次的对象的 QuerySet,这可以带来更好的性能并显着减少内存。

这是 django 文档的引用:https ://docs.djangoproject.com/en/dev/ref/models/querysets/#iterator

于 2012-11-09T16:36:16.620 回答