2

GAEで、私のハンドラーはすべての面倒な作業を行う関数を呼び出します。すべてのオブジェクトは関数内に作成されます。ただし、関数が終了した後(response.out.writeの文字列を返す)、メモリ使用量は減少しません。GAEへの最初のhttp呼び出しは機能しますが、その後、メモリは約100MBのままになります。プライベートメモリの制限に達したため、2回目のアクセス試行は失敗します。

私が作成したすべてのクラス静的オブジェクトをクリアし、サードパーティライブラリのcloseおよびclear関数を呼び出しましたが無駄になりました。どのようにしてメモリをきれいに解放しますか?メモリリークを追跡するよりも、強制的に再起動したいです。ここではパフォーマンスは問題ではありません。

私はそれがGCによるものではないことを知っています。GAEは、メモリが長期間高レベルにとどまっていると報告しています。上記の2つのhttp呼び出しは、数分以上離れていました。

Handler.get関数で関数のインポートを実行しようとしました。ページを提供した後、インポートしたすべてのサードパーティモジュールを削除してから、自分のモジュールを削除しようとしました。理論的には、各呼び出しで疑わしいすべてのモジュールが再起動するはずですが、メモリの問題は解決しません。呼び出しの間に残される唯一の(意図された)モジュールは、標準ライブラリモジュール(lxml、xmlなどを含む)である必要があります。

編集:タスクキューを使用してバックエンドインスタンスでヘビーデューティー部分をスケジュールし、db.Blobを使用して結果を渡します。バックエンドを機能させると、メモリの問題が解決します。バックエンドに関するGAEのドキュメントは完全ですが、紛らわしいものです。重要なのは、1)backends.yamlの編集2)appcfgを使用した更新(ランチャーからのデプロイでは不十分)の指示に従う必要があるということです。その後、管理者にバックエンドが稼働していることを確認します。また、taskqueue target =は開発サーバーで中断するため、開発サーバーで回避する必要があります。

4

1 に答える 1

2

これは (おそらく)ガベージ コレクター(未使用のメモリの解放を担当) が関数が返されたときに直接起動するという記述がないためです。

いくつかのハックを介して手動で強制的に起動することもできますが、2 つの http リクエストがほぼ同時に発生した場合、何も解決しません。同時に。

代わりに、リクエストごとに面倒な作業を行う必要のないソリューションを検討することをお勧めします。

生成されたデータがリクエストごとに一意である場合は、(制限された) プライベート メモリ プールの外で計算を実行できるかどうかを確認してください。


ガベージ コレクターを手動で開始するにはどうすればよいですか?

重い変数が範囲外になったら、以下のメソッドを使用して GC を呼び出します。

import gc

...

gc.collect ()
于 2012-10-20T05:54:05.917 に答える