ノード N のツリー T があります。T は、監視しているプログラムによって行われたすべてのメモリ割り当てと割り当て解除の記録を表します。GUI は「count」と「bytes」をチェックします
public class Node
{
private Dictionary<int, Node> Children = new Dictionary<int, Node>();
private int count; // Total allocs for all _leaves_ below
private int bytes; // Total bytes allocated for all _leaves_ below
protected void Instantiate( StackTrace stackTrace, int index ) { ... }
protected void Increment( StackTrace stackTrace, int size, int index ) { ... }
protected void Decrement( StackTrace stackTrace, int size, int index ) { ... }
}
public class Root : Node
{
private void UpdateTree( StackTrace[] stackTraces ) { ... }
}
監視スレッドはツリー マネージャーにスタック トレースのバッチを渡し、ツリー マネージャー (スタックが割り当てとしてラベル付けされている場合) を通過し、スタック トレース内のメソッドごとにツリー上にノードを作成します (ラベル付けされていない場合)。既に存在します)、system32.dll までずっと。これは正常に動作します。
これが完了したら、ツリーを並行して更新しようとしています(機能していません):
private void UpdateTree( StackTrace[] stackTraces )
{
ForEach(stackTrace in stackTraces)
{
if (HasntBeenInstantiated(stackTrace))
Instantiate(stackTrace, 0);
}
Parallel.ForEach (allocs, alloc =>
{
if (alloc is AllocationEvent)
T.Increment(alloc.stack, alloc.size, 0);
else if (alloc is DeallocationEvent)
T.Decrement(alloc.stack, alloc.size, 0);
});
}
private void Instantiate( Stack stack, int size, int index )
{
if (++index < stack.Length)
GetOrAddNewChild(stack[index]).Instantiate(stack, index);
}
private void Increment( Stack stack, int size, int index )
{
Interlocked.Increment(ref count);
Interlocked.Add(ref bytes, size);
if (++index < stack.Length)
GetChild(stack[index]).Increment(stack, index);
}
private void Decrement( Stack stack, int size, int index )
{
Interlocked.Decrement(ref count);
Interlocked.Add(ref bytes, -size);
if (++index < stack.Length)
GetChild(stack[index]).Decrement(stack, index);
}
すべてのバッチで、すべてのリーフ ノードに対して、割り当て解除よりも多くの割り当てイベントが発生することが保証されています。しかし、どういうわけか、バッチを処理した後、一部のノードで負のカウントおよび/または負のバイトが発生することがあります。 上記の何かが間違っていますか?
ノート:
更新にはヒステリシスがないため、ロックとミューテックスを避けています。すべてのデータが正しく入力される限り、各バッチの最後に数値が正しくなるはずです。
編集:
受信データにエラーがあったことがわかりました。