web-dev-qa-db-ja.com

javascriptで「弱い参照」を作成することは可能ですか?

Javascriptに別のオブジェクトへの「弱い参照」を作成する方法はありますか? これがウィークリファレンスとは何かを説明するwikiページです。Javaでそれらを説明する別の記事があります。 javascriptでこの動作を実装する方法を考えることができますか?

85
Stephen Cagle

JavaScriptにはweakrefの言語サポートはありません。手動の参照カウントを使用して独自にロールできますが、特にスムーズではありません。 JavaScriptオブジェクトでは、いつガベージコレクションが行われるのかがわからないため、プロキシラッパーオブジェクトを作成することはできません。

したがって、「弱い参照」は、add-referenceおよびremove-referenceメソッドを使用した単純な検索のキー(整数など)になり、手動で追跡された参照がなくなったときにエントリを削除して、将来の検索をオンのままにすることができますnullを返すキー。

これは実際にはweakrefではありませんが、同じ問題のいくつかを解決できます。通常、DOM Nodeまたはイベントハンドラーとそれに関連するオブジェクトとの間に参照ループがある場合、ブラウザー(通常IE、特に古いバージョン)からのメモリリークを防ぐために、複雑なWebアプリケーションで行われます。これらの場合、完全な参照カウントスキームは必要ない場合もあります。

37
bobince

NodeJSでJSを実行する場合、 https://github.com/TooTallNate/node-weak を検討できます。

14
Scholle

真のウィークリファレンス、いや、まだです(ただし、ブラウザメーカーはこの問題に注目しています)。しかし、ここでは弱参照をシミュレートする方法についてのアイデアがあります。

オブジェクトを駆動するキャッシュを構築できます。オブジェクトが保存されると、キャッシュはオブジェクトが占有するメモリ量の予測を保持します。画像の保存など、一部のアイテムでは、これは簡単に解決できます。他の人にとっては、これはもっと難しいでしょう。

オブジェクトが必要になったら、キャッシュを要求します。キャッシュにオブジェクトがある場合、それが返されます。存在しない場合は、アイテムが生成、保存され、返されます。

予測されるメモリの合計量が特定のレベルに達すると、キャッシュがアイテムを削除することにより、弱参照がシミュレートされます。どのアイテムが最も頻繁に取得されるかに基づいて、どのアイテムが最も使用されていないかを予測します。アイテムを作成するコードがクロージャーとしてキャッシュに渡される場合、「計算」コストも追加できます。これにより、キャッシュは構築または生成に非常に高価なアイテムを保持できます。

削除アルゴリズムが重要です。これを誤ると、最も人気のあるアイテムを削除してしまう可能性があるためです。これはひどいパフォーマンスを引き起こします。

キャッシュがpermanentが格納されたオブジェクトへの参照を持つ唯一のオブジェクトである限り、上記のシステムは真の弱参照の代替としてかなりうまく機能するはずです。

3
JL235

参照用です。 JavaScriptにはありませんが、ActionScript 3(ECMAScriptでもあります)にはあります。 辞書のコンストラクターパラメーター を確認してください。

2
Amir

最後に彼らはここにいます。ブラウザにはまだ実装されていませんが、すぐに実装されます。

https://v8.dev/features/weak-references

1

JL235 推奨 上記 のように、キャッシングメカニズムを使用して弱参照をエミュレートするのが妥当です。弱参照がネイティブに存在する場合、次のような動作が観察されます。

this.val = {};
this.ref = new WeakReference(this.val);
...
this.ref.get(); // always returns val
...
this.val = null; // no more references
...
this.ref.get(); // may still return val, depending on already gc'd or not

一方、キャッシュを使用すると次のことを確認できます。

this.val = {};
this.key = cache.put(this.val);
...
cache.get(this.key); // returns val, until evicted by other cache puts
...
this.val = null; // no more references
...
cache.get(this.key); // returns val, until evicted by other cache puts

参照の保持者として、値を参照するタイミングについて仮定するべきではありません。これはキャッシュを使用しても同じです

1
Markus