ディープバインディングを備えた静的/字句スコープの言語があり、クロージャーを作成するとします。クロージャーは、実行したいステートメントといわゆる参照環境、またはこの投稿を引用すると、使用できる変数のコレクションで構成されます。
この参照環境は実際に実装的にどのように見えるのでしょうか? 私は最近、ObjectiveC のブロックの実装について読んでいました。著者は、バックグラウンドでスタック上のすべての変数とヒープ オブジェクトへのすべての参照のコピーを取得することを提案しています。説明では、クロージャーが作成された時点で参照環境の「スナップショット」を取得すると主張しています。
- それは多かれ少なかれ起こることですか、それとも私はそれを読み違えましたか?
- ヒープオブジェクトの別のコピーを「凍結」するために何かが行われていますか?それとも、クロージャーの作成とクロージャーの実行の間にそれらが変更された場合、クロージャーはオブジェクトの元のバージョンで動作しなくなると想定しても安全ですか?
- 実際にコピーが行われている場合、多くのクロージャーを作成してどこかに保存したい状況で、メモリ使用に関する考慮事項はありますか?
これらの概念の一部を誤解すると、このブログ投稿で Eric Lippert が言及しているような厄介な問題につながる可能性があると思います。クロージャーが呼び出されるまでになくなる可能性のある値型への参照を保持するのは意味がないと思うので興味深いですが、C# ではコンパイラーは変数が後で必要になり、代わりにヒープに入れます。
ほとんどのメモリ管理言語ではすべてが参照であるように思われるため、ObjectiveC は、スタック上にあるもののコピーに対処しなければならないというやや特殊な状況です。