Python 如何阻止Flask和NLTK的内存泄漏

Python 如何阻止Flask和NLTK的内存泄漏,python,performance,memory-leaks,nltk,Python,Performance,Memory Leaks,Nltk,我正在使用NLTK和Flask构建一个web应用程序。这只是一个简单的RESTful应用程序,我在heroku上部署了它,一切都很顺利。但是,当服务器开始收到更多请求时,我达到了heroku的内存限制,即1.5GB。所以,我猜这是因为每次请求到来时我都在加载nltk.RegexpParser 这是非常简单的代码 @app.route('/get_keywords', methods=['POST']) def get_keywords(): data_json = json.load

我正在使用NLTK和Flask构建一个web应用程序。这只是一个简单的RESTful应用程序,我在heroku上部署了它,一切都很顺利。但是,当服务器开始收到更多请求时,我达到了heroku的内存限制,即1.5GB。所以,我猜这是因为每次请求到来时我都在加载
nltk.RegexpParser

这是非常简单的代码



@app.route('/get_keywords', methods=['POST'])
def get_keywords():
    data_json = json.loads(request.data)
    text = urllib.unquote(data_json["sentence"])
    keywords = KeywordExtraction().extract(text)

    return ','.join(keywords)
这是关键词提取位


import re
import nltk

nltk.data.path.append('./nltk_data/')

from nltk.corpus import stopwords

class KeywordExtraction:
    def extract(self, text):

        sentences = nltk.sent_tokenize(text)
        sentences = [nltk.word_tokenize(sent) for sent in sentences]
        sentences = [nltk.pos_tag(sent) for sent in sentences]

        grammar = "NP: {}"
        cp = nltk.RegexpParser(grammar)
        tree = cp.parse(sentences[0])

        keywords = [subtree.leaves()[0][0] for subtree in tree.subtrees(filter=lambda t: t.node == 'NP')]
        keywords_without_stopwords = [w for w in keywords if not w in stopwords.words('english')]

        return list(set(keywords_without_stopwords + tags))
我不确定这是否是我的代码、Flask或NLTK的问题。我对Python很陌生。任何建议都将不胜感激


我通过blitz.io对此进行了测试,仅在250个请求之后,服务器就崩溃并开始抛出R15。

从缓存开始:

# Move these outside of the class declaration or make them class variables

stopwords = set(stopwords.words('english'))
grammar = "NP: {}"
cp = nltk.RegexpParser(grammar)
这也可以加快一点:

from itertools import ifilterfalse

...

keywords_without_stopwords = ifilterfalse(stopwords.__contains__, keywords)

return list(keywords_without_stopwords + set(tags))  # Can you cache `set(tags`)?

我还想看看Flask Cache,以便尽可能多地记忆和缓存函数和视图。

您可以将
cp
设置为静态类变量(请参阅)。我怀疑这能解决你的问题。您也可以使用stopwords.words('english')来尝试,这样您就不会创建该列表的很多实例。然后,您应该只创建一个关键字提取器并一直使用它,而不是在每个请求中创建一个关键字提取器。