2

在 GAE 上,我的处理程序调用一个函数来完成所有繁重的工作。所有对象都在函数内创建。然而,在函数退出后(它返回一个用于 response.out.write 的字符串),内存使用量并没有下降。对 GAE 的第一次 http 调用有效,但之后内存保持在 100MB 左右。第二次访问尝试失败,因为已达到私有内存限制。

我已经清除了我编写的所有类静态对象,并调用了第三方库的 close 和 clear 函数,但无济于事。如何干净地释放内存?我宁愿强制重启而不是追踪内存泄漏。性能在这里不是问题。

我知道这不是由于GC。GAE 报告内存在很长一段时间内保持在高水平。上面的两个 http 调用相隔几分钟或更长时间。

我试图在 Handler.get 函数中导入我的函数。提供页面后,我尝试删除所有导入的第三方模块,然后删除我自己的模块。理论上,现在每个调用都应该重新启动所有可疑模块,但内存问题仍然存在。调用之间剩下的唯一(预期)模块应该是标准库模块(包括 lxml、xml 等)。

编辑:我现在使用 taskqueue 在后端实例上安排繁重的部分,并使用 db.Blob 来传递结果。让后端工作解决了内存问题。后端的 GAE 文档是完整的,但令人困惑。关键是需要遵循以下说明 1) 编辑 backends.yaml 2) 使用 appcfg 进行更新(从启动器部署是不够的)。然后在管理员中检查后端是否已启动。taskqueue target= 在开发服务器上也中断,因此需要在开发服务器上解决它。

4

1 回答 1

2

这(可能)是因为没有什么说垃圾收集器(负责释放未使用的内存)会在您的函数返回时直接启动。

您可以通过一些技巧手动强制它启动,但如果两个 http 请求发生 aprox,这将无法解决任何问题。同时。

相反,我建议您查看不需要您对每个请求进行繁重工作的解决方案。

如果生成的数据对于每个请求都是唯一的,请查看您是否可以在(有限的)私有内存池之外进行计算。


如何手动启动垃圾收集器?

当您的重量级变量超出范围时,请使用以下方法调用 GC。

import gc

...

gc.collect ()
于 2012-10-20T05:54:05.917 回答