我的Flask有一个小内存泄漏,通过许多API调用导致我的应用程序达到它的内存限制和崩溃。我一直在试图弄清楚为什么一些内存没有被释放,但到目前为止没有成功,我相信我知道消息来源。我很感谢你的帮助!
不幸的是,我无法共享代码,但为了用英语描述它,我的烧瓶应用程序提供了一个API端点,供用户执行以下操作(所有这些都是在一个调用中完成的):
据我所知,使用剖面图库时,我看到内存使用量最多的两个区域是文档对象的初始化和连接/保存到S3 (分别为7MB和4.8MB )。
为了监视Python进程的内存使用情况,我要让psutils打印出在某些关键点使用的rss内存(下面的示例代码)。
process = psutil.Process(os.getpid())
mem0 = process.memory_info().rss
print('Memory Usage After Action',mem0/(1024**2),'MB')
## Perform some action
mem1 = process.memory_info().rss
print('Memory Usage After Action',mem1/(1024**2),'MB')
print('Memory Increase After Action',(mem1-mem0)/(1024**2),'MB')提供的控制台映像是在我在本地托管应用程序三次之后提供的。

关注的是,每个顺序的API调用似乎都是从上次调用离开内存使用量并继续添加的位置开始的。应用程序以93 it启动(见黄色高亮显示),但在第一次调用结束后,它以103.79MB结束,第二个调用以103.87MB开始,最后一个调用以105.39MB结束,第三个调用以105.46Mb开始,最后一个以106MB结束。虽然使用量在减少,但在100次调用之后,我仍然看到了内存的增量使用。红线和蓝线显示API调用期间各个点的内存变化。红线在文档生成之后,蓝线在S3上传之后。
请注意,我的测试程序每次都用相同的参数调用API。
除其他事项外,我还测试了以下内容:
我知道,因为我不能提供代码,所以这里可能没有太多的内容,但是如果没有任何想法,我想知道是否有一种处理烧瓶内存使用的最佳实践方法,或者在烧瓶函数返回一些东西之后清除内存的方法。现在,我的烧瓶函数是相对标准的Python函数(因此,我希望这个函数中的局部变量随后会被垃圾收集)。
我正在使用Python3.6、Flask0.11.1和pymongo3.6.1,我的测试现在正在windows 7机器上进行,但我的IBM云服务器也遇到了同样的问题。
发布于 2020-10-11 17:16:58
几年后,我应该更新一下。因为我在一条评论中发表了这样的评论,除非有人找到了更好的解决方案,否则我会把它作为“答案”。
不幸的是,我无法完全解决这个问题,不得不继续前进,但我能够将增量消耗减少到这样一个点,即如果我们接近极限,定期的维护和监视将清除剩余的/通知。
减少调用之间增量内存消耗的最大原因是启动另一个线程来处理Flask端点中的内存锁定任务,等待线程完成,一旦完成,就会杀死线程。就像我说的那样,它没有完全解决这个问题,并且确实引入了开销,但是它减少了内存泄漏问题,我们可以通过上述步骤来接受它。这是创可贴的修复。因此,如果存在另一种/更好/真正的解决方案,请随意提出建议。
谢谢您,@above_c_level为调试瓶中的内存泄漏提供了有用的提示。
发布于 2021-02-10 03:24:53
这种行为只发生在开发环境中的调试模式中,但是当我使用服务员作为web服务器时,我的烧瓶应用程序在没有内存泄漏的情况下工作正常。
这是我要从虚拟环境运行的app.waitress。
import sys
import os
import site
from waitress import serve
dir_path = os.path.dirname(__file__)
sys.path.append(os.path.abspath(dir_path))
venv_packages = os.path.abspath(os.path.join(dir_path, 'venv', 'lib', 'site-packages'))
sys.path.append(venv_packages)
site.addsitedir(venv_packages)
from dotenv import load_dotenv
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
load_dotenv(dotenv_path)
from settings import API_HOST, API_PORT
from app import app as application
serve(application, host=API_HOST, port=API_PORT)若要从终端(Mac或Linux)运行它,请执行以下操作:
. venv/bin/activate
pip install waitress
python app.waitress要从Windows运行它:
py -3 -m pip install waitress
py app.waitress环境:
Python 3.7.9
waitress 1.4.1
Flask 1.1.2
Flask-Cors 3.0.10
Flask-JWT-Extended 3.25.0
python-dotenv 0.10.3https://stackoverflow.com/questions/49991234
复制相似问题