[52] HTML や DOM は様々なオブジェクトやそれに類するもので構成されています。 それらは文書 (Webアプリケーション) を構成する要素として存在していたり、 スクリプトによって操作されたりします。どこからも参照されなくなり、 スクリプト上も利用者界面上も意義を失ったオブジェクト等はごみ収集され、 破棄されます。それはすなわち Webブラウザー実行環境のメモリーから削除され、 動作もアクセスもできなくなることを意味します。
[107] Webブラウザーはごみ収集を実装しなければなりません。
[109] 具体的な方法は規定されていません。実装は任意の方法を選択できます。
[110] 単なる参照カウンターでは、循環参照を持ち外部から参照されなくなったオブジェクト群を回収できません。 著者のスクリプトが循環参照を破棄することは求められていませんから、 メモリリークが発生してしまいます。仕様書のアルゴリズムも循環参照の破棄はしていませんから、 実装時には注意が必要です。
[84] Web と JavaScript においてはごみ収集の具体的な手法は実装依存となっており、 その挙動は著者から観測可能であるべきではないと考えられています。
[85] 言語によってはオブジェクトが破棄される直前に特定のメソッドが呼び出されるなどの仕組みがありますが、 Web にはそれに類するものはありません。
[96] この原則に反する新機能の導入は避けるべきだと考えられており、 回避できないために断念された機能もあります。
[98] ごみ収集の詳細を著者 (スクリプト) から観測可能にしてしまうと、 Webブラウザーの実装の進化を阻害してしまう危険性があります。
[99] 例えばごみ収集には様々な手法が存在しますが、 特定のタイミングで特定の処理が実行されることを保証しようとすると、 それを実現可能なごみ収集手法の実装を強制することになり、 ごみ収集手法の改良を妨げてしまうおそれがあります。 逆に当該処理の詳細な実行タイミングを定義しないと、 ごみ収集その他の実装の差異によって、実装ごとに異なるタイミングで処理が実行され、 相互運用性の問題が生じる可能性があります。
[100] live なコレクションは、対象となるDOM木の変更が反映されますが、 実装上はリアルタイムで変更を反映させる必要はなく、 スクリプトからアクセスがあった時まで変更の反映を遅延させることもできます。 あるいは、節点のリストを途中までだけ作成したり、 リストの一部だけ変更を反映させた状態にしたりと、 色々な実装方針が考えられ、どれを採用するかは各実装の裁量です。
[101] さてDOM木から節点が削除され、スクリプトからも参照されなくなった時、 その節点はおそらくコレクションからも削除されることになりますが、 ごみ収集が実行可能になるタイミングは、コレクションの更新のタイミングに依存します。 ごみ収集が観測可能になると、コレクションの実装方法にも制約が生じます。
[102] 多くの Webブラウザーでは console.log
により、あるいは開発者ツールにより JavaScript オブジェクトにアクセスできます。
つまり開発者ツールからオブジェクトへの参照が生じます。 スクリプト側での GC
のタイミングに制約があるとすると、開発者ツール側で参照が残っていてもスクリプト側では開放したことにしなければならず、
より実装が複雑になるかもしれません。 (少なくても実装方法への制約は強くなると思われます。)
[51] HTML も DOM も、「ごみ収集」、 「強参照」、「弱参照」 といった用語を定義なしで使っており、計算機科学分野での一般的な単語として用いていると思われます。 (なお HTML は「弱参照」という用語を使っていません。)
[80] JavaScript には WeakMap
と WeakSet
があります。
[119] その他にいくつか仕様書上の概念が弱参照を使っています。
[70] 環境設定群オブジェクトの未決拒絶された約束弱集合は、 そのメンバーに対して強参照を作ってはならない >>36 と規定されています。
[3] 既存のオブジェクトを返すIDL属性からは、そのオブジェクトへの暗示強参照があります。 >>2
[4] 例えば、 window.document
IDL属性により、
Window
オブジェクトから Document
オブジェクトは強い参照があることとなります。
[79] オブジェクトには、しばしば IDL属性として直接外部から参照可能でなくとも、 内部的な属性のようなものとして別のオブジェクトが関連付けられていることがあります。 これも強参照が存在し、最初のオブジェクトが存在する限り関連付けられているオブジェクトも破棄されないものと思われます。
[87] オブジェクト同士の参照は、直接または間接に循環していることがあります。例えば、
親節点から子節点へは childNodes
を通じて参照がありますし、
子節点から親節点へは parentNode
を通じて参照があり、循環しています。
また JavaScript によって著者が容易に循環参照を作り出すことができます。
[88] 従って Web におけるごみ収集は、外部から参照されなくなった循環参照のあるオブジェクト群を回収できる手法を用いる必要があります。
[93] ごみ収集の実装手法の中には、ごみ収集の処理のために本来のプログラムの動作をすべて停止する必要があるものもあります。
[94] 明示的な規定は存在していないものの、利用者に明確に判別可能なレベルで動作を停止させるような実装方法は、 好ましくないと考えられます。
[95] Acid3 はそのアニメーションが滑らかであることを要求しており、 この試験に通過するためには、実行途中でごみ収集によって速度が変化するような実装であってはいけません。
[13] 利用者エージェントは最上位閲覧文脈に対して強参照を持っています。 >>11
[12] 閲覧文脈は、その Document
群とその WindowProxy
に対して強参照を持っています。 >>11
[14] Document
はその Window
に対して強参照を持っています。逆に
Window
は document
属性を通じて暗示強参照を持っています。 >>11
[15] Window
は window
など、
Document
は defaultView
などを通じて
WindowProxy
への暗示強参照を持っています。 >>11
[16] スクリプトはスクリプト設定群オブジェクトへの強い参照を持っており、 スクリプト設定群オブジェクトは大域オブジェクト、有責閲覧文脈、 有責文書に対して強参照を持っています。 >>11
[19] 最上位閲覧文脈でない閲覧文脈の WindowProxy
がごみ収集の対象になると、
当該閲覧文脈は閲覧文脈を捨てる算法により処理されなければなりません。 >>11
[45] 節点は、登録済み観察器のリストにある登録済み観察器に対する強参照を持ちます。 逆方向には弱参照を持ちます。 >>44
[21] DedicatedWorkerGlobalScope
/Worker
は暗示的に関連付けられた MessagePort
オブジェクトを有しますが、この MessagePort
は
DedicatedWorkerGlobalScope
/Worker
より先にごみ収集してはなりません。 >>20, >>24
[23] ワーカーの実行時誤りは error
事象として呼び出し元の Worker
や
Document
へと伝達されていきますが、その伝達先が既にごみ収集されて消失している場合には
onerror
は null
であるものとして
(つまり何もしないで更に上位の呼び出し元へと伝達されるよう) 処理されます。 >>22
[90] ワーカーはスクリプト設定群オブジェクトを介してワーカーを起動した大域オブジェクトや
Document
への参照を保有しています。
MessagePort
[39] MessagePort
についてはオブジェクト自身が著者のスクリプトから参照されなくなっても、
相手方が存在する限り存続することがあります。
MessagePort
参照。[81] MessagePort
の一端が失われた場合に他方に通知する方法も検討されたものの、
ごみ収集の挙動をスクリプトから観測できず、メモリーリークもさせず、
bfcache も実装可能であるような手法が見つからず、議論がまとまりませんでした。
[39] PortCollection
は MessagePort
を零個以上保有することができるオブジェクトですが、強参照ではないので
MessagePort
のごみ収集を防ぐ役割は持たず、
ごみ収集された MessagePort
は削除されていきます。
しかしこれもごみ収集の実装の自由を損なうとして、実装されることはありませんでした。
BroadcastChannel
[38] BroadcastChannel
参照。
[47] 画像データの更新算法の実行中は、
その対象となっている img
要素の文書から当該要素への強参照があるとしなければなりません。
>>46
[83] canvas
のヒット領域は、削除されたり消去されて対応する画素がなくなり、
他のヒット領域の子供でもないなら、領域をごみ収集する手順により削除されます
>>82。
[7] 媒体要素は、それに対するすべての参照が削除されただけの理由で再生を停止してはなりません。 それ以上音声を再生できない状態になった時、当該媒体要素はごみ収集して構いません。 >>6
[8] 要素に対して明示的に参照が存在しておらず、まだ活性的に再生されていなくとも、 音声の再生のために存在し続けることがあります。例えばまだ参照されている現在媒体制御器があって再生再開できるかもしれませんし、 あるいは再生再開されていてもバッファ待ちのため stall 中かもしれません。 >>6
[54] XMLHttpRequest
オブジェクトは次の場合ごみ収集してはなりません。
>>53
[62] XMLHttpRequest
オブジェクトの接続が開いたままごみ収集される場合、
fetch をすべて取り消し、それらにより追加されたタスクをすべて破棄し、
またそれらによりネットワークから受信しているデータがあれば破棄しなければなりません。
>>61
[26] EventSource
については、
readyState
が
CONNECTING
であり、かつ open
, message
,
error
のいずれかの事象聴取器が登録されている場合EventSource
の readyState
が
OPEN
であり、かつ message
,
error
のいずれかの事象聴取器が登録されている場合... には、 EventSource
の構築子が呼び出された Window
または WorkerUtils
から EventSource
への強参照がなければなりません。 >>26
[30] EventSource
の接続が開いている間に同オブジェクトがごみ収集される場合、当該オブジェクトによって開かれた
fetch は中断しなければなりません。 >>26
[32] WebSocket
オブジェクトは、
イベントリスナーやバッファーの状況次第で、ごみ収集してはなりません >>31。
[37] また WebSocket
オブジェクトが接続が開いたままごみ収集される場合は、
接続を閉じる手順を実行しなければなりません >>31。
WebSocket
のごみ収集を参照。Notification
[92] Notification
は、対応する通知が list of pending notifications
か list of active notifications に含まれていて、
click
, show
, error
, close
のいずれかのイベントリスナーを持つ間は、これをごみ収集してはいけません >>91。
[1] Web におけるごみ収集 (garbage collection) は HTML Living Standard ではじめて明示的に規定され、 その後他の仕様でも定義されるようになりました。
[73] オブジェクトが著者がアクセスできる範囲の外から参照されることもあり得ます。例えば
console.log
メソッドにオブジェクトを渡すと、
その環境のデバッガーが当該オブジェクトへの参照を保持し、
スクリプト内から参照しなくなったとしてもごみ収集されずに残り続けることがあります。
[75] Incremental GC in Firefox 16! | JavaScript ( ( 版)) <https://blog.mozilla.org/javascript/2012/08/28/incremental-gc-in-firefox-16/>
[76] JavaScript:SpiderMonkey:GC Futures - MozillaWiki ( ( 版)) <https://wiki.mozilla.org/JavaScript:SpiderMonkey:GC_Futures>
[77] substructural: Programming, Entrepreneurship, and the Markets: Garbage Collection in JavaScript, Part 1 ( ( 版)) <http://www.typedynamic.com/2012/03/garbage-collection-in-javascript.html>
[78] Web Applications 1.0 r2529 MAJOR CHANGES: Revamp the way scripts are specified, along with their interaction with resolving relative URLs, etc. Give enough detail to justify objects in the DOM not being garbage collected randomly when still in use. Define script groups, to handle scripts going away during document.open() and session history navigation. Define why and how setTimeout(), database transactions, etc, handle page transitions. Drop the terms 'with' and 'without' script, use script is 'enabled'/'disabled' instead. Define 'unload' and 'beforeunload'. Rework how onfoo= and .onfoo event handler attributes are defined. Rework how the content model of <noscript> is defined. Reword the way javascript: is defined to use the new terminology. Add a few notes of things that came up while I was doing all that.]] ( ( 版)) <http://html5.org/tools/web-apps-tracker?from=2528&to=2529>
[89] エデンの園でおきたこと - steps to phantasien ( (Hajime Morrita 著, 版)) <http://steps.dodgson.org/b/2012/12/19/dom-and-gc-or-what-happend-at-eden/>
[103] Bug 25223 – IDB exposes GC behavior ( ( 版)) <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25223>
[104] Bug 26515 – Change when media elements may be garbage collected ( ( 版)) <https://www.w3.org/Bugs/Public/show_bug.cgi?id=26515>
[105] Specify life time management · Issue #15 · yutakahirano/fetch-with-streams ( 版) <https://github.com/yutakahirano/fetch-with-streams/issues/15#issuecomment-72119046>
[33] Feature suggestion - event from the JS Garbage Collector · Issue #238 · WebAssembly/design ( 版) <https://github.com/WebAssembly/design/issues/238>
[34] Add description for suspension, resuming and garbage collection · whatwg/fetch@1dfbd1f ( 版) <https://github.com/whatwg/fetch/commit/1dfbd1f6284e4cb0aae91a8b9db36a2dc11393b1>
[114] Move structured cloning out from under Common DOM Interfaces · whatwg/html@e09b782 ( 版) <https://github.com/whatwg/html/commit/e09b7824480ffc9df69b0d830c4b8adad3b000d1>
[115] Clarify settings object, realm, and global relationships · whatwg/html@0866f1b ( 版) <https://github.com/whatwg/html/commit/0866f1b3f4b4ea5a99a30909e9bbe557dea0b460>
[116] Custom elements disconnected from a document should not be upgraded · Issue #419 · w3c/webcomponents ( ()) <https://github.com/w3c/webcomponents/issues/419>
[117] Workers: Curtail the browser's license to kill · Issue #1004 · whatwg/html () <https://github.com/whatwg/html/issues/1004>
[41] GC / DOM / Web API Integration :unicorn: - WebAssembly () <http://webassembly.org/docs/gc/>
[43] Abortable fetch (jakearchibald著, ) <https://github.com/whatwg/fetch/commit/0bcd5dfc71ef44319873887f4b83119bd6d0b71d>
[121] Sensor must not expose GC behavior (pozdnyakov著, ) <https://github.com/w3c/sensors/commit/9fd7eeb7a69635ea9e3b0f4eb0402c677bba19e5>
[122] Must not expose GC behavior to the web · Issue #337 · w3c/sensors () <https://github.com/w3c/sensors/issues/337>
[123] Sensor must not expose GC behavior by pozdnyakov · Pull Request #338 · w3c/sensors () <https://github.com/w3c/sensors/pull/338>
[124] Permit freeing underlying source / sink / transformer after close · Issue #932 · whatwg/streams () <https://github.com/whatwg/streams/issues/932>