問題タブ [reference-counting]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 作成不可能な COM オブジェクトの参照カウンターをより適切に初期化するにはどうすればよいですか?
オブジェクトを返すメソッドを持つ COM インターフェイスがあります。
重要なのは、呼び出しがインターフェイスICreatorInterface::CreateObject()
を実装するオブジェクトを取得する唯一の方法であるということです。IObjectToCreate
C++ では、次のようにできます。
またはこの方法
違いは、参照カウンターの初期化方法と、QueryInterface()
失敗した場合のオブジェクト削除の実装方法です。CCreatorInterfaceImpl
私は両方を完全にコントロールしているのでCObjectToCreateImpl
、どちらの方法でも行くことができます。
IMO 最初のバリアントはより明確です。すべての参照カウントは 1 つのコードに含まれています。私は何かを監督しましたか?なぜ 2 番目のアプローチの方が優れているのでしょうか。上記のどれがより良いですか、そしてその理由は何ですか?
excel - イベントの頻度を数える
一連の株価データ データがあり、価格が上昇または下降した日数をカウントできるようにしたいと考えています。たとえば、データから、ある日が上か下かを判断するために「if」関数を使用しました。「U」はアップ日、「D」はダウン日です。文字列は次のようになります。
ううっどどどどどぅぅ
上昇が 3 日、下降が 2 日、上昇が 1 日、下降が 1 日などをカウントする数式が必要です。そうすれば、一方向の価格変動がどれくらい続いたかのプロファイルを作成できます。 ..結果をヒストグラムまたはチャートで表示したい。
必要な結果を得るために使用できる式または関数を知っている人はいますか?
どんな助けにも感謝します。ありがとう
c++ - 参照カウントを取得するには、API を shared_ptr で乱雑にする必要がありますか?
最近、次のメモリ バグが発生しました。ここでは簡単に見つけることができますが、より複雑なコードでは検出が難しくなる可能性があります。
バグは、Bar
すぐに範囲外になり、破棄されてから で使用されることfoo->test()
です。Bar
1 つの解決策は、を使用してヒープ上に作成することBar* bar = new Bar()
です。ただし、特定のコードブロックに固有のものであっても、最後にBar* bar
アクセスできるようにポインターをトップレベルに保持する必要があるため、これを行うのは好きではありません。delete
Bar
if(whatever){}
別の解決策は ですがboost::shared_ptr<Bar>
、これだけを書くことはできません:
もすぐに範囲外になりshared_ptr
、含まれているオブジェクトが破棄されるためです。
要するに、この問題を取り除くには、どこでも、メンバー変数として、のコンストラクターなどを使用shared_ptr
する必要があります。これらの問題を一般的に解消するには、すべての API などで を使用する必要があります。醜い。しかし、それは正しいことですか?これまでのところ、参照カウント オブジェクトを作成するために時々使用してきましたが、API をクリーンな状態に保っています。一度使用すると、どこでも使用しなければならないというこの問題にどのように対処しますか?Foo
Foo
shared_ptr
shared_ptr
shared_ptr
(また、これらの参照カウント ポインターを使用する場合は、本当に必要shared_ptr
かどうかweak_ptr
などについて心配し始める必要があります。)
そして、私は何を同等のものとして使用しFoo(const Bar& bar)
ますか? Foo(const shared_ptr<const Bar> bar)
?
もちろん、別のオプションとして、Bar
および他のオブジェクト内に参照カウントを追加pimpl
し、独自のカウンターを使用することもできますが、一般的なルールとしては面倒です。
algorithm - 共有メモリ内の参照カウントの問題を効率的にデバッグするにはどうすればよいですか?
共有メモリに参照カウント オブジェクトがあるとします。参照カウントはオブジェクトを使用するプロセスの数を表し、プロセスはアトミック命令を介してカウントを増減する責任があるため、参照カウント自体も共有メモリにあります (オブジェクトのフィールドまたはオブジェクトのフィールドである可能性があります)。カウントへのポインターが含まれている可能性があります。この問題の解決に役立つ場合は、提案を受け付けています)。場合によっては、プロセスにバグがあり、カウントをデクリメントできないことがあります。どのプロセスがカウントを減少させていないかをできるだけ簡単に把握するにはどうすればよいでしょうか?
私が考えた解決策の 1 つは、各プロセスに UID (おそらく PID) を与えることです。次に、プロセスが減少すると、UID を参照カウントと一緒に保存されたリンク リストにプッシュします (リンク リストを選択したのは、CASを使用してヘッドにアトミックに追加できるためです)。デバッグする場合、共有メモリ内でまだ生きているオブジェクトのリンクされたリストを調べる特別なプロセスがあり、リストにないアプリの UID は、まだカウントを減らしていないアプリです。
このソリューションの欠点は、N がプロセスの数である場合、O(N) のメモリ使用量があることです。共有メモリ領域を使用するプロセスの数が多く、多数のオブジェクトがある場合、これはすぐに非常に高価になります。単一のプロセスを特定できなくても、部分的な固定サイズ情報を使用して、可能なプロセスのリストを何らかの方法で絞り込むことができ、デバッグを支援できる中途半端な解決策があるのではないかと思います。または、1 つのプロセスだけが減少していないときにどのプロセスが減少していないかを検出できた場合 (つまり、カウントの減少に失敗した 2 つ以上のプロセスの検出を処理できない場合)、それはおそらく大きな助けになるでしょう。
(この問題には、すべてのアプリケーションが同じライブラリを使用して共有メモリ領域にアクセスするようにするなど、より「人間的な」解決策がありますが、共有領域がバイナリ インターフェイスとして扱われ、すべてのプロセスが によって作成されたアプリケーションになるわけではありません。また、すべてのアプリが同じライブラリを使用している場合でも、1 つのアプリにライブラリの外部にバグがあり、カウントを減らすことができないような方法でメモリを破壊している可能性があります。 C/C++ ;)
編集:単一プロセスの状況では、制御できるため、RAII (C++) を使用できます。
c# - COMに公開されたCLRオブジェクトをカウントするCOM参照を傍受(または認識)することは可能ですか?
私はこの質問を言い換えました。
.netオブジェクトがCOMiteropを介してCOMクライアントに公開されると、CCW(COM Callable Wrapper)が作成され、これはCOMクライアントとマネージド.netオブジェクトの間に配置されます。
COMの世界では、オブジェクトは他のオブジェクトが参照している数をカウントします。その参照カウントがゼロになると、オブジェクトは削除/解放/収集されます。これは、COMオブジェクトの終了が決定論的であることを意味します(決定論的終了には.netのUsing / IDisposeを使用し、オブジェクトファイナライザーは非決定論的です)。
各CCWはCOMオブジェクトであり、他のCOMオブジェクトと同様に参照カウントされます。CCWが停止すると(参照カウントがゼロになる)、GCはCCWがラップしたCLRオブジェクトを見つけることができず、CLRオブジェクトは収集の対象になります。幸せな日々、すべてが世界とうまくいっています。
私がやりたいのは、CCWが停止したとき(つまり、参照カウントがゼロになったとき)をキャッチし、これをCLRオブジェクトに通知することです(たとえば、管理対象オブジェクトでDisposeメソッドを呼び出すことによって)。
では、 CLRクラスのCOM呼び出し可能ラッパーの参照カウントがいつゼロになるかを知ることは可能ですか?
および/または
.netでCCWのAddRefおよびReleaseRefの実装を提供することは可能ですか?
そうでない場合は、これらのDLLをATLに実装することもできます(ATLのサポートは必要ありません。ありがとうございます)。ロケット科学ではありませんが、実世界のC ++やATLを社内で開発しているのは私だけなので、やりたくありません。
背景
私はいくつかの古いVB6ActiveXDLLを.netで書き直しています(正確にはC#ですが、これはC#の問題というよりも.net / COMの相互運用の問題です)。古いVB6オブジェクトの一部は、オブジェクトが終了したときにアクションを実行するために参照カウントに依存しています(上記の参照カウントの説明を参照)。これらのDLLには重要なビジネスロジックは含まれていません。これらは、VBScriptを使用して統合するクライアントに提供するユーティリティおよびヘルパー関数です。
私がやろうとしていないこと
- ガベージコレクタを使用する代わりに、カウント.netオブジェクトを参照します。私はGCに非常に満足しています、私の問題はGCにありません。
- オブジェクトファイナライザーを使用します。ファイナライザーは非決定論的です。この場合、決定論的終了が必要です(.netのUsing / IDisposeイディオムなど)
- アンマネージC++でIUnknownを実装
するC++ルートを使用する場合は、ATLを使用します。ありがとうございます。 - Vb6を使用してこれを解決するか、VB6オブジェクトを再利用します。この演習の全体的なポイントは、Vb6へのビルドの依存関係を取り除くことです。
ありがとう
BW
受け入れられた回答は、唯一の(おそらく実行可能な).netベースの回答を考案したSteve Steinerと、非常に単純なATLソリューションを考案したEarwicker
に感謝します。
しかし、受け入れられた答えはBigtoeに行きます。彼は、.netオブジェクトをVbScriptオブジェクト(私は正直だとは思っていませんでした)でラップし、VbScriptの問題に対する単純なVbScriptソリューションを効果的に提供することを提案しています。
ありがとうございます。
cocoa - これはCocoa参照カウントの正しい要約ですか?
これが私の理解です:
オブジェクトは保持されるだけです(参照カウンターがインクリメントされます):
init
fromNSObject
が呼び出されたとき。retain
が呼び出されたとき。
オブジェクトは解放されるだけです(参照カウンターはデクリメントされます):
release
が呼び出されたとき。- オブジェクトを含む自動解放プールが排出されたとき
また、明確にするために、自動解放は保持せず、オブジェクトを自動解放プールスタックの最上位のプールに配置するだけです。
binary-tree - AVL ツリー内の重複キーの処理
サポートの重複キーを作成したいavl-tree
のですが、with duplicates のデフォルトの動作に問題がありbinary search tree
、ローテーションによって同じキーを持つノードが親の左右に配置される可能性があります。
たとえば、すべてキー A を持つ 3 つのノードを追加すると、ツリーは次のように回転します。
したがって、そのキーですべてのエントリを取得することは問題になります...そして、双方向の検索は良くありません。
私が考えた解決策は、各ノードに重複の配列を格納することです。そのため、既に存在する新しいアイテムを追加すると、新しいアイテムが配列に追加され、キーでアイテムを削除するとノード全体が削除され、すべてのアイテムが検索されますwith key はその配列を返します。
重複を処理する他の方法はありますか?
挿入項目はキーと値を受け取ります..したがって、特定のキーメソッドを使用してfindAllで値を返すために、値を保存する必要があります。
c++ - ページの粒度よりも細かい特定のメモリ位置への書き込みが発生した場合、強制的にクラッシュさせることはできますか?
パフォーマンス上の理由から共有メモリを使用するプログラムを作成しています(代替手段としてのソケットとパイプが評価されており、これらは私のタスクには十分な速度ではありません。一般的に、コピーを含むIPCメソッドは遅すぎます)。共有メモリ領域では、固定サイズの多くの構造体を書いています。構造体を共有メモリに書き込むためのプログラムが1つあり、そこから読み取る多くのクライアントがあります。ただし、クライアントが書き込む必要のある各構造体のメンバーは1つです(参照カウント。アトミックに更新されます)。他のすべてのメンバーは、クライアントに対してのみ読み取る必要があります。
クライアントはその1つのメンバーを変更する必要があるため、共有メモリ領域を読み取り専用としてマップすることはできません。ただし、他のメンバーをいじくり回してはいけません。これらのプログラムはC ++で記述されているため、メモリが破損する可能性があります。理想的には、あるクライアントが別のクライアントをクラッシュさせることは可能な限り困難である必要があります。私はバグのあるクライアントについてのみ心配しており、悪意のあるクライアントについては心配していないので、不完全な解決策は許可されています。
ヘッダーでconstとして使用するメンバーを宣言することで、クライアントによる上書きを阻止することができますが、それでもメモリの破損(バッファオーバーフロー、不正なキャストなど)による上書きを防ぐことはできません。カナリアを挿入することはできますが、それをチェックするための費用を常に支払う必要があります。
参照カウントメンバーを直接保存する代わりに、構造体を読み取り専用のマップされたページに保持しながら、実際のデータへのポインターを別のマップされた書き込み専用ページに保存することができます。これは機能します。ポイントされたデータに書き込もうとすると、OSによってアプリケーションが強制的にクラッシュしますが、ロックフリーアルゴリズムを書き込もうとすると、間接ストレージが望ましくない場合があります。これは、別のレベルの間接参照に従う必要があると、何かができるかどうかが変わる可能性があるためです。アトミックに行われます。
メモリの小さな領域にマークを付けて、それらを書き込むとアプリが爆発するようにする方法はありますか?一部のプラットフォームにはハードウェアウォッチポイントがあり、インラインアセンブリでそれらの1つをアクティブ化できるかもしれませんが、32ビットx86では一度に4つに制限され、それぞれが制限されているため、構造体の一部しかカバーできませんでした4バイトまで。また、プログラムをデバッグするのが面倒になります;)
編集:私はこのかなり目を見張るような紙を見つけましたが、残念ながら、ECCメモリと変更されたLinuxカーネルを使用する必要があります。
c++ - 構成によって参照カウントを実装しても問題ありませんか?
最も一般的な再利用可能な参照カウント オブジェクトは、プライベート継承を使用して再利用を実装します。私はプライベート継承の大ファンではないので、これが許容できる処理方法であるかどうかに興味があります。
または、私が見ていないこれに微妙な問題がありますか?
編集
私はこの特定の実装にあまり関心がありません(おそらくバグがあります-本番コードでこのようなものを使用する前に、shared_ptrの内部を調べることに時間を費やします)-一般的には心配です再利用可能な参照カウント機能が常に構成ではなく継承を使用して実装されているように見える特定の理由があります。
python - Cコードを処理する際のPython参照カウント/ガベージコレクションの落とし穴はありますか?
そのため、 PythonをSchemeプログラムに埋め込むことができるように、libpythonにバインドするSchemeを作成することにしました。私はすでにPythonのCAPIを呼び出すことができますが、メモリ管理についてはあまり考えていません。
mzschemeのFFIが機能する方法は、関数を呼び出すことができ、その関数がへのポインターを返す場合PyObject
、参照カウントを自動的にインクリメントさせることができます。次に、Schemeオブジェクトがガベージコレクションされたときに参照カウントをデクリメントするファイナライザーを登録できます。参照カウントのドキュメントを確認しましたが、一見したところ問題はありません(ただし、場合によっては最適ではない場合もあります)。私が見逃している落とし穴はありますか?
また、サイクリックガベージコレクタのドキュメントの先頭または末尾を作成するのに問題があります。ここで心に留めておくべきことは何ですか?特に、Pythonに何かへの参照があることを認識させて、まだ使用している間はそれを収集しないようにするにはどうすればよいですか?