在App Engine后端实例上完成请求后何时释放内存?

时间:2017-07-11 06:28:37

标签: google-app-engine google-app-engine-python

方案 -

我在App Engine上运行B *实例。我在App Engine上安排了作为cron作业的后台ETL相关任务(用python编写)。 当时间到来时,cron启动一个http请求来启动任务并运行而不返回响应,直到任务完成。 当任务执行时,它通常消耗“X”MB的RAM。任务完成并返回200 OK后,App Engine实例监控仍显示正在使用的“X”MB RAM。

请帮助我理解以下内容 -

  1. 如果一个实例只运行一个任务,并且在完成它之后,什么时候会释放这个任务消耗的内存?
  2. 我是否需要运行gc.collect()来明确调用垃圾收集器以释放RAM?
  3. 释放RAM的唯一方法是重启实例?
  4. PS:这与NDB完全无关,我的任务是从Bigquery获取输入,执行一些ETL操作,然后将其流式传输到Bigquery。

2 个答案:

答案 0 :(得分:2)

StackOverflow上有一些问题描述了在app引擎上使用ndb时类似的内存问题。这是一个example

问题是app引擎在任务结束时没有清除ndb上下文缓存,因此上下文缓存会在任务完成后很长时间内继续占用你的内存。

解决方案是在任务期间不使用或清除上下文缓存。以下是几种方法:

  • 使用ndb.get_context().clear_cache()
  • 绕过缓存
  • 在适当的时间致电_use_cache = False
  • 通过向模型定义添加Dim wsThis As Worksheet Dim aCell As Range Sheets("URR").Columns(1).copy Destination:=Sheets("SAP Pull").Columns(22) Set wsThis = Sheets("SAP Pull") With wsThis For Each aCell In .Range("V2:V") .Cells(aCell.Row, 23) = Application.WorksheetFunction.VLookup( _ aCell.Value, wsThat.Range("A2:D3500"), False) Next aCell End With End Sub 来禁用某种实体的缓存。

答案 1 :(得分:1)

根据我对使用大量内存进行StringIO操作的应用程序的观察:

  • 明确地调用gc.collect()没有明显的帮助(我甚至怀疑我实际上有内存泄漏,但事实并非如此)

  • 在每个请求之后内存不会被释放,但是,如果实例保持活动的时间足够长而没有内存耗尽,那么它最终会被释放 似乎偶尔会被释放。易于测试 - 只需增加请求之间的时间,以降低可用内存耗尽率。但我无法弄清楚一个可用的模式。请注意,我只是在升级到B2个实例后观察到这一点,我的B1个实例内存耗尽太快,我从未注意到它们的释放事件。

  • 使用具有更多内存的instance class(我尝试将其实例作为最终耗尽内存的实例)帮助 - 内存似乎更频繁地被释放。 可能因为这些实例也有更快的CPU(但这只是猜测)。