PDA

View Full Version : Ext.Windowのメモリリーク回避方法について



Mari
25 May 2009, 4:52 PM
お世話になります。

Ext.Windowで、
 ・modal:true
 ・closeAction:指定なし(デフォルトで'close')
としたモーダルを作成したのですが、開く→閉じるを繰り返すと、ブラウザのメモリ使用量がどんどん増えていってしまいます。

以下のページに、同様の現象が記載されているようなのですが、closeAction:'close'は使用しないほうが良いということなのでしょうか?
close();を実行すると、内部でdestroyが行われているようなので、問題ないように思えるのですが・・・。
http://extjs.com/forum/showthread.php?t=19910 (http://extjs.com/forum/showthread.php?t=19910)

回避方法として、良い手段はありますでしょうか?
よろしくお願いします。

○環境
 Extのバージョン 2.1
 ブラウザ:IE 6.02

amanoman
26 May 2009, 3:45 PM
destroyは明示的にコールする必要もないし、コンポーネントの外側のdomに何かを追加した時や、直接domにイベント追加した時や、別のオブジェクトにイベントを追加した時以外は、destroyメソッドにロジックを書く必要は無いと思います。
(3.0では、直接domにイベント追加した時も、明示的に開放する必要がなくなりました。)
モーダル時の透過処理に問題があるみたいですね。
IEのメモリーリークは、原因が複数存在する場合が多いので、とりあえず、問題解決にはならないかも知れなけど、2.2.1にバージョンアップしてみてはどうでしょうか?
(複数のIEにおけるメモリーリーク問題が改善されています。)
参考までに。

Mari
27 May 2009, 12:04 AM
ご回答ありがとうございます。

2.2.1にバージョンアップできればそうしたいのですが、現状の工程が既に終盤ですので、
今の状態からのバージョンアップは難しそうです。

また、以下のスレッドで、2.2.1のバージョンを使用していても、同様の現象でお困りの方もいらっしゃいました。
http://extjs.com/forum/showthread.php?t=63527&highlight=memory
こちらでもまだ回答が出ていないようでした・・・。

yuki
27 May 2009, 3:13 AM
簡単なコードを書いて再現しようとしたのですが、Windowの開閉を繰り返してもうまく再現できませんでした。
現象を再現するサンプルコードは可能でしょうか?

Mari
27 May 2009, 10:33 PM
サンプルを作成してみました。
  →メモリリークサンプルCahceFly版.zip
IE6で添付のsample.htmlを実行して、モーダルを表示し、閉じる→開く を繰り返してください。

しかし、こちらの環境でも実行してみましたが、やはりExtのバージョンが関係しているかもしれません。
サンプルはCahceFlyを使用しておりますため、バージョンは2.2.1かと思います。
その場合、多少はメモリが増えますが、そこまではリークしないように思います。
こちらの環境は、Ext2.1ですので、もしその環境がございましたら、添付の
  →メモリリークサンプル.zip
を回答し、中身の4ファイルをExt2.1直下に配置し、sample.htmlを実行してください。
メモリがどんどん増えていきます。

よろしくお願いします。

Mari
27 May 2009, 10:35 PM
失礼しました。
添付いたします。

yuki
28 May 2009, 6:52 PM
2.1でメモリーがどんどん増加していくのを確認しました(最初、間違って2.2で確認してました)
・・・
さて、色々と調べてみたのですが、Ext.Window単体で問題を解決する方法は見つけられてないのですが、下記の方法であればメモリー著しい増加は防げるようです:



(Ext JS 2.2.1の source/core/EventManager.js を ext-all.jsの後に読み込み)
・・・
・・・
Ext.override(Ext.Element, {
removeAllListeners: function(){
Ext.EventManager.removeAll(this.dom);
return this;
}
});


2.1→2.2でEventManagerの中身がかなり変更されていて、それに伴って、ElementのremoveAllListenersの中身が変更されています。Elementについてはoverrideできるのですが、EventManagerについてはクロージャを使って変数をプライベート化しているのでoverrideが使えないため、上記のような方法をとっています。

ただ、2.1→2.2にアップグレードしたときにエラーが起きてしまう、という場合、大体EventManagerがらみ(Ext.onReadyとか)だったりするので、上記方法でメモリーの問題が解決したとしても、別の問題が発生するような気がします・・・

一番いいのは、最新バージョンにアップグレードすることなんですが(後々のメンテナンスのことも考えると急がば回れかと)・・・

Mari
31 May 2009, 5:17 PM
ご回答ありがとうございます。
やはり、アップグレードを検討したほうが良いですか:((。
ご提案いただきました修正案でも別の問題が発生する可能性があるのであれば、テストをしなおす必要があると思いますので、アップグレードをした場合と同様の確認をしなくてはならないですし・・・。

今の段階では難しいとは思いますが、検討してみます。
もし他に良い修正案などございましたら、ぜひご教授下さい。
よろしくお願いします。

Mari
9 Jun 2009, 5:43 AM
現在、Extのバージョンアップを行うかどうか検討中なのですが、バージョンをあげなかった場合、以下の方法は有効でしょうか?

Ext.Window.prototype.onDestroy = function(){
if(this.manager){
this.manager.unregister(this);
}
Ext.Window.superclass.onDestroy.call(this);
if (!this.mask) return;
delete this.mask;
}

http://extjs.com/forum/showthread.php?t=19910
のスレッドに上げられていたものなのですが、全てのリークは解消できないかも知れませんが、大部分が解消できるというのであれば、全体に影響が少ないこの方法で、と思うのですが・・・。