1

そこで、約 800k のドキュメントを処理するデーモンを go で作成しましたが、メモリ不足の問題が発生しています。

mongodb からドキュメントを取得したときに見たものから、メモリ使用量はループごとに増加します。

func main() {
session, err := mgo.Dial("localhost")
if err != nil { panic(err) }
defer session.Close()

subscriptionsC  = session.DB("sm").C("subscriptions")
subscriptions   := []Subscription{}

for {
    subscriptions = GetSubscriptions()

そして、他の機能は次のとおりです。

func GetSubscriptions()([]Subscription) {
    result  := []Subscription{}
    err    := subscriptionsC.Find(nil).Prefetch(0.0).All(&result)

    if err != nil { Log("signups_err", err.Error() + "\n") }
    return result
}

ループごとに配列を再宣言しているのか、それとも正確に何が起こっているのかはわかりません。

どんな助けでも大歓迎です。

4

2 に答える 2

1

mgo の作者はこちら。

コードに問題はありませんが、不完全であるため、表示されていないものが実際にメモリ リークを起こしている可能性は常にあります。

メモリリークの完全な例を提供できますか?

ちなみに、mgo はリソースのプールを内部的に処理するため、セッションのキャッシュ/プールには意味がありません。あなたがしなければならないことは、作成したセッションを確実に閉じることです。これはサンプル コードで行われます。

以下のOPのコメントの後に更新します。

問題は大量のドキュメントにあるようです。pastebin.com/jUDmbS4z これは 10 ~ 15 分ごとに 1 回 (約 4 ~ 5 ループ) クラッシュします。1 つのループで mongo から約 600k ドキュメントを取得しています。

ええ、一度に大量のデータをメモリにロードするクエリを実行すると、mgo とは関係のない多くの理由で簡単に問題が発生する可能性があります..メモリの断片化、不正確なコレクターなど。これは快適で、高速で、使用するメモリの量を劇的に削減します。

于 2014-01-13T14:15:27.240 に答える
0

GetSubscriptions()配列は、 loop への呼び出しとループ内での呼び出しのために、すべてのループで間違いなく初期化されていますが、それresult := []Subscription{}は問題の原因ではないと思います。

問題は、グローバル セッションから発生している可能性があります。Web アプリケーションでのデータベース接続を参照してください。適切な方法は、セッション プールを使用することです。

編集:ハンドラーから mongoDB CRUD メソッドを呼び出すにはどうすればよいですか?も参照してください。

于 2014-01-07T13:52:28.787 に答える