XSLTProcessorを使い回して何度もtransformToFragmentさせていたらDFが解放されてなかった件
なんか関係なかったかも…… うーん
XULアプリxwitterというtwitterクライアントを個人的に作っていて、まぁユーザは僕一人なんですが、手に馴染んでいるし、ほしい機能は自分で追加できるので愛用しています。
xwitterではtwitterのRESTレスポンスXMLをXSLTでXHTMLに変換しているのですが、ずっとメモリリークしていて困っていました。クロージャまみれなので、その辺なのかなぁと疑ってはみたものの、なかなか解決しなかったのですが、今朝ふと気づいたのが掲題の件です。
該当部分のコードを抜き出すと、まずXSLTProcessor生成関数。
var xsltproc = function(path) { var doc = document.implementation.createDocument('', '', null); doc.async = false; doc.load(path); var proc = new XSLTProcessor(); proc.importStylesheet(doc); return proc; };
XSLTかける度に毎回newしていてはコストがかかるだろうなぁと思って、最初にプロセッサを作るだけにしていました。
var myXsltproc = xsltproc('chrome://xwitter/content/xwitter.xsl');
XSLT変換をかけて、XHTMLのDOMツリーにinsertBeforeしているところ。
var df = myXsltproc.transformToFragment(xml, document); _box.insertBefore(df, _box.firstChild);
そして、メモリ圧迫してきたら、そのDOMツリーを空にする処理。
_box.style.display = 'none'; _box.innerHTML = ''; _box.style.display = 'block';
しかし全くガーベジコレクションされていないようです。おかしい。insertBefore後dfは参照しませんし、DOMツリーからも抹消しているのに。どうやらmyXsltprocがずっとDocumentFragmentを掴んでいるみたいでした。解放するメソッドとかないんでしょうか。resetメソッドというのがありましたが、remove all stylesheets and parameters
と書かれています。せっかくimportStylesheetしたのを消されても困りますし、もう一度newするコストと比べて軽いのかどうかも怪しい感じです…… 仕方なくXSLT変換の度に毎回newすることにしました…… これでしばらく様子を見ます……