为什么在函数返回后没有释放内存?

时间:2012-10-20 05:44:20

标签: google-app-engine memory-leaks python-2.7

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

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

我知道这不是因为GC。 GAE报告记忆长时间处于高水平。上面的两个http调用分开了几分钟或更长时间。

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

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

1 个答案:

答案 0 :(得分:2)

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

你可以手动强制它通过一些黑客攻击,但如果两个http请求发生aprox,这将无法解决任何问题。在同一时间。

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

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


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

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

import gc

...

gc.collect ()