0

バックグラウンド

5 月に、メモリ保持の問題に関する WebKit の問題を報告しました。問題は Web Inspector 自体に起因する可能性があるように見えますが、まだ確信が持てません。

問題

私の JavaScript アプリケーションが、利用可能になったデータを取得するための「 Polling Consumer 」パターンを実装するという問題が表面化しました。問題は、記憶が保持され、1 日を通して増加することです。JavaScript ロジックは次のようになります。

  1. データを取得して折り返し電話する
  2. コールバックされたら、データを処理してからステップ 1 を実行します

これは JavaScript でポーリング コンシューマを実装する合理的な方法ですか? ちなみに、私はjQueryのajax関数を使用していますが、もちろんそれ自体に問題がある可能性があります。さらに、成功ハンドラーとしてjQueryプロキシを使用しているため、スコープによる保持は問題にならないと考えていました。また、プロキシを使用せずに問題を観察しました。いくつかのコード:

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
...
    success: function(data) {
      // Do some processing
      // Call back in a short while...
      setTimeout($.proxy(self.getFids, self), 100);
    },
...
  });
);
4

1 に答える 1

1

のコピーが 1 つしかないのgetFidsは良いことですが、呼び出されるたびに 2 つの新しい関数を作成することになります。1 つは成功ハンドラー用で、もう 1 つは$.proxy呼び出しからのものです。これら 2 つの関数は、呼び出しごとに一意ではありません。それらを再利用可能な変数に入れると、多くの余分な関数を作成する必要がなくなり、メモリ リークの可能性が大幅に低下します。

コンストラクターで、オブジェクトごとに 1 回、各関数のプロキシ バージョンを作成する例。呼び出しを繰り返しても、それ以上関数は生成されません。

function FidsDataController() {
  // ...constructor...


  // Proxy these functions just once from the prototype
  this.getFids = $.proxy(this.getFids, this);
  this._getFids_success = $.proxy(this._getFids_success, this);
}

FidsDataController.prototype.getFids = function() {
  var self = this;
  $.ajax({
    success: this._getFids_success;
  });
};

FidsDataController.prototype._getFids_success = function(data) {
  // processing of data
  setTimeout(this.getFids, 100);
};
于 2010-09-14T02:08:12.147 に答える