Canvas使用時のJavaScriptメモリ消費量の解析
canvasを使用していると思わぬjavascriptのheapに遭遇することがあるが、
原因をつかむのが難しい。。
調べてみるとGoogleChromeの機能でメモリ解析機能があるとのことで試してみる。
(参考)Chromeの知られざる開発者向け機能 - JavaScriptメモリ消費量の解析
http://news.mynavi.jp/articles/2011/05/31/chrome/index.html
GoogleChrome->ディベロッパーツール->Profiles->TakeHeapSnapShot->Start
スタートをクリックするとその時点でのヒープのスナップショットが取得され、
使用状況を関数単位で表示してくれる。
開始時点と数分後を比較すると一目瞭然で、時間に比例してArrayやclosure、Object
のRetailnedSizeが上昇していくことが分る
出力結果を参照して、イベントを調べていくとクロージャーやループイベントで頻発。
イベントハンドラの設定時にクロージャで循環参照するのが原因ぽいことが判明。
クロージャでスコープが複雑に関わってくるときメモリリークは多発するとの話題が色々なブログで掲載されていた。
※クロージャ周りのメモリリークはIE7/Fx2では修正されてるとも書かれているが。
で、解決方法として下記を散々読んだ挙句、2つ対策を実施。
(参考)クロージャとメモリリークについてのコピペ
http://d.hatena.ne.jp/lesamoureuses/20080416/1208325055
1.クロージャに取り込む変数に最後null代入する(参A)
2.addEventListenerを使用した後はremoveEventListenerする
(参A)
function test() { var elt = document.getElementById('i0'); elt.src = 't2.png'; elt.onclick = function() { location.href = 't2.html'; } }
function test() { var elt = document.getElementById('i0'); elt.src = 't2.png'; elt.onclick = function() { location.href = 't2.html'; } elt = null; }
ひとまず上記の対策で、javascriptのheapは回避できた様子。
(参考)
クロージャとメモリリークについてのコピペ
http://d.hatena.ne.jp/lesamoureuses/20080416/1208325055
Javascriptメモリリークについて
http://ncwiki.commonsnet.org/develop/index.php?Javascript%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
循環参照のはなし
http://www.slideshare.net/hiratara/ss-10539893
IE でのメモリリーク
http://nanto.asablo.jp/blog/2005/12/04/165848
JavaScript イベントハンドラの循環参照
http://sandbox.serendip.ws/javascript_event_handlers_element.html
[JavaScript]JavaScriptでクロージャで循環参照でメモリリーク。
http://d.hatena.ne.jp/shunsuk/20110510/1305022708
addEventListenerで渡した無名関数の中でremoveEventListenerする
http://d.hatena.ne.jp/nacookan/20080308/1204982293