[英]How does app engine (python) manage memory across requests (Exceeded soft private memory limit)
我在app引擎中的各种请求处理程序中偶尔会遇到Exceeded soft private memory limit
错误。 我知道这个错误意味着实例使用的RAM超过了分配的数量,以及它如何导致实例关闭。
我想了解可能导致错误的原因,并且首先,我想了解app引擎python实例应该如何管理内存。 我的基本假设是:
这就是我认为这是可行的,但考虑到我偶尔会穿过一个相当广泛的一系列请求处理程序中看到这个错误,现在我不那么肯定。 我的问题是:
a)第4步会发生吗?
b)什么可能导致它不发生? 还是不完全发生? 例如,请求之间的内存如何泄漏?
c)模块级变量中的存储是否会导致内存使用泄漏? (我不是故意以这种方式使用模块级变量)
d)我可以使用哪些工具/技术来获取更多数据? 例如,在请求处理程序的入口处测量内存使
在答案/评论中,如果可能,请链接到gae文档。
[编辑]额外信息:我的应用程序被设置为threadsafe: false
。 如果这与答案有关,请说明它是什么。 我打算改成threadsafe: true
很快。
[编辑] 澄清:这个问题是关于gae对内存管理的预期行为 。 因此,虽然像'call gc.collect()
'这样的建议可能是相关问题的部分解决方案,但它们并没有完全回答这个问题。 直到我理解gae预期如何表现gc.collect()
,使用gc.collect()
会让我感觉像伏都gc.collect()
程序。
最后:如果我把这一切都倒退了,那么我提前道歉 - 我真的找不到有用的信息,所以我大多猜测..
与任何其他标准Python解释器相比,App Engine的Python解释器在内存管理方面没有什么特别之处。 因此,特别是“每个请求”没有任何特殊情况,例如您的假设步骤4.相反,只要任何对象的引用计数减少到零,Python解释器就会回收内存(模块gc
仅用于处理垃圾循环 - 当一堆对象永远不会将它们的引用计数降为零,因为它们相互引用,即使它们没有可访问的外部引用)。
所以,如果你使用任何全局变量,内存很容易“泄漏”(实际上,虽然从技术上说它不是泄漏)“请求之间” - 所述变量将在处理程序类的实例及其(例如) get
方法中存活 -即你的观点(c),尽管你说你没有这样做。
一旦您将模块声明为threadsafe
,实例可能会同时为多个请求提供服务(直到您在模块的.yaml
配置文件的automatic_scaling
部分中设置为max_concurrent_requests
;默认值为8)。 因此,您的实例的RAM需要是每个请求所需的倍数。
至于(d),为了“获取更多数据”(我想你实际上是指,获得更多内存),你唯一能做的就是为需要内存的模块配置一个更大的instance_class
。
要使用更少的RAM ,有许多技术 - 与App Engine无关,与Python有关,特别是与您的特定代码及其特定需求有关的一切。
我能想到的一个GAE特定问题是据报道ndb
的缓存泄漏 - 请参阅https://code.google.com/p/googleappengine/issues/detail?id=9610 ; 该线程还建议了解决方法,例如关闭ndb
缓存或移动到旧db
(没有缓存且没有泄漏)。 如果你正在使用ndb
并且没有关闭它的缓存,那可能是你正在观察的“内存泄漏”问题的根本原因。
第4点是一个无效的假设,Python的垃圾收集器不会轻易返回内存,Python的程序占用了那个内存但是在垃圾收集器通过之前它不会被使用。 与此同时,如果某些其他请求需要更多内存 - 可能会在第一个请求的内存之上分配新内存。 如果要强制Python进行垃圾收集,可以使用此处提到的gc.collect()
请查看此问答,了解检查垃圾收集的方法以及可能的替代解释: Google App Engine数据库查询内存使用情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.