1

ガベージ コレクションのアイデアを得るために、Chrome ヒープ プロファイラーといくつかの基本的なバックボーン オブジェクトをいじっています。不思議で紛らわしい行動に出くわしました。

jquery-1.7.2、underscore-1.3.3、および backbone-0.9.2 のみが読み込まれたベース ページを使用します。Chrome (win/19) js コンソール ウィンドウから次のコードを実行すると、コレクションはガベージ コレクションされません。ヒープ プロファイラーの「オブジェクトの保持ツリー」では、50 人のユーザーと、モデルとコレクションの間の循環参照が一覧表示されますが、function() @234234 で b と言う 2 つも一覧表示されます。これらの参照を展開すると、参照は jQuery の ajax コールバック ハンドラからのもののように見えます。

(function () {
    var collection = new Backbone.Collection();
    collection.url = '/api/users/';
    collection.fetch();

    setTimeout(function wtf() { $('#content').append($('<div>' + collection.models[0].get('name') + '</div>')); }, 3000);
})()

次のコードを実行すると、コレクションは期待どおり適切にガベージ コレクションされます。違いは、コレクションから jQuery ajax コールバックをシフトしているように見えるランダムな ajax 呼び出しを行う最後の行です。

(function () {
    var collection = new Backbone.Collection();
    collection.url = '/api/users/';
    collection.fetch();

    setTimeout(function wtf() { $('#content').append($('<div>' + collection.models[0].get('name') + '</div>')); }, 3000);

    $.ajax({ url: '/api/users/' });
})()

これは予想される動作ですか、それともバグですか? 過去に ajax リクエストを行っていたためにランダムなオブジェクトがぶら下がっていたら、それは最悪です。

更新:これをさらにテストしていたので、最初または2番目のインスタンスにのみ影響するようです。新しいコレクションを作成し、1 秒ごとにフェッチを呼び出す setinterval を作成すると、最初に作成された 1 ~ 2 個のインスタンスが無期限に (20 分以上) メモリに残り、作成された他のすべてのインスタンスは適切に破棄されます。

jquerys Ajax関数を呼び出し、成功ハンドラーでデータを作成時のパラメーターとして新しいコレクションに渡すと、この動作はまったく発生しません。作成されたすべてのインスタンスは適切にクリーンアップされます。

関数 Backbone.wrapError は、成功のラッピングとともに問題の一部であるようです。

4

0 に答える 0