【问题标题】:Does Python garbage collect when Heroku warns about memory quota vastly exceeded (R15)?当 Heroku 警告内存配额大大超出 (R15) 时,Python 是否会收集垃圾?
【发布时间】:2026-01-26 06:35:01
【问题描述】:

我在 Heroku 上的 Celery 下运行了一个后台任务,即经常出现“错误 R14(超出内存配额)”和偶尔出现“错误 R15(超出内存配额)”。我正在从数据库中加载很多东西(通过 Postgres 上的 Django),但它应该加载一个大对象,处理它,然后处理引用并加载下一个大对象。

我的问题是,垃圾收集器是否知道在达到 Heroku 的内存限制之前运行?我应该手动运行 gc 吗?

还有一点就是我的任务有时候会失败,然后Celery会自动重试,就成功了。它应该是确定性的。我想知道任务完成后是否有东西在内存中徘徊,并且在下一个任务开始时仍然占用空间。重新启动工作进程会清除内存并让它成功。也许 Django 或 DB 有一些缓存没有被清除?

我使用的是标准 2 倍尺寸。我可以去 performance-m 或 performance-l,但尽量避免这样做,因为它会花费更多的钱。

【问题讨论】:

  • 我怀疑python进程知道内存配额,所以我猜它不会运行垃圾收集器。无论哪种方式,手动垃圾收集仅在少数可以释放大量内存但未达到自动收集阈值的边缘情况下有用。您更有可能只是使用了大量内存,在这种情况下垃圾收集无法清理任何东西。
  • 你能粘贴你正在获取对象的工作代码吗?这里可能有问题,也许你没有使用生成器或加载东西太急切。 Heroku 给出的内存错误意味着您将开始使用交换内存(在磁盘上),这非常慢。最终,如果你的内存达到交换内存的 1.5 倍,Heroku 将重新启动你的进程,而 celery 将重新尝试任何作业。

标签: python django heroku garbage-collection celery


【解决方案1】:

看起来问题是我没有使用.iterator() 来迭代主查询集。即使我在每次迭代后释放我正在创建的数据结构,实际的查询结果都会被缓存。

很遗憾,我不能使用.iterator(),因为我广泛使用prefetch_related

我需要某种混合方法。我认为这将涉及批量处理*查询集。它不会完全具有prefetch_related 具有的有限数量的查询的优势,但它会比每个模型对象一个查询要好。

【讨论】:

  • 你还记得你是如何解决这个问题的吗?我也遇到了这个问题。
  • 对不起,我不记得了。如果您有同样的问题,请为问题投票,如果不是答案。
最近更新 更多