私は、各インスタンスにデータを格納するPython GAEアプリケーションを使用しています。実例として、私は私のアプリに追加した。このテストコードを考えてみます。クエリ変数nの値でこのハンドラへの呼び出しは、それぞれ10のリストにn個の文字列を追加するには、インスタンスが発生します Google App Engineで予期せずメモリ使用量が高い
from google.appengine.ext import webapp
bucket = []
class Memory(webapp.RequestHandler):
def get(self):
global bucket
n = int(self.request.get('n'))
size = 0
for i in range(n):
text = '%10d' % i
bucket.append(text)
size += len(text)
self.response.out.write('Total number of characters = %d' % size)
文字は長い。
これをn = 1(ロードするすべてを取得する)と呼び、プロダクションサーバーでインスタンスメモリの使用状況を確認すると、29.4MBという数字が表示されます。 n = 100000で呼び出してもう一度チェックすると、メモリ使用量は38.9MBになりました。つまり、私のメモリ占有量は9.5MB増えて100万文字しか保存できませんでした。これは私が期待していたものの10倍近くです。文字はそれぞれ1バイトしか消費しないと信じていますが、間違っていてもまだまだ道のりはまだまだです。リスト構造のオーバーヘッドは確かに説明できません。明示的なガベージコレクションコールを追加しようとしましたが、数値は変更されませんでした。何が欠けていますか?フットプリントを減らす方法はありますか?
(ちなみに、私はリストの代わりにセットを使ってみましたが、n = 100000で呼び出すとメモリ使用量が13MB増加しました。これは、100000文字列の設定オーバーヘッドがリストより3.5MB多く、また、予想よりもはるかに大きい)。
私は文字カウントが「大幅に」過少にメモリ使用量かもしれないことに同意します:彼らは、設定されたサイズは、ハッシュ衝突を回避するために、アレイ内の十分な空きスロットを持つために成長するように、メモリの使用量に大きなジャンプを持つ終わります、しかし10のファクターによって?あなたのインスタンスのメモリは、断片化のために実際のデータが10%、ゴミが90%だと言っていますか? trueの場合、問題は、Google App Engine内の非効率的なメモリ割り当てアルゴリズムほど断片化されていない可能性があります。malloc()は決して悪くありませんでした。 – Dragonfly
「malloc」に関する私の経験は異なります。そのサンプルコードが何をしているか再度見てください。これは、リストをバックアップする基礎となるメモリ領域の定期的な成長を引き起こし、データをコピーしている間に新旧のコピーを少なくとも生きているように保ちます。間に新しい文字列を作成しています。それはヒープを分割することになります。 –