2009-11-24 4 views
4

Я ищу управляемый/неуправляемый API, который позволит мне найти, какие объекты ссылаются на другой объект и потенциально не позволяют ему собирать мусор.Получить активные ссылки на объект

Такой API может выглядеть следующим образом:

var foo = new Foo(); 
var bar = new Bar(); 
bar.Foo = foo; 

var references = GC.GetReferencesTo(foo); 
// references is an array that contains bar 

Я знаю профайлер можно использовать для этого, но я хотел бы сделать его частью модульного тестирования. Есть ли управляемый или неуправляемый API, который я мог бы использовать?

+1

См. Этот вопрос: http://stackoverflow.com/questions/1786083/how-do-i-iterate-through-instances-of-a-class-in-c/1786354#1786354 –

ответ

5

Неуправляемая dll SOS (Son Of Strike) обеспечивает средства для достижения этой цели, хотя я не верю, что она имеет значительную поддержку сценариев и не обеспечивает простого средства для достижения этой цели с помощью одной команды. Вам нужно будет исследовать адрес переменной, проверить все gcroots для переменной (которая, очевидно, будет содержать стек), и иметь дело с остатком.

Я хотел бы предложить, что, если вы хотите, чтобы доказать, что объект не ссылки, более простой метод будет (временно) сделать его финализации, убедитесь, что больше не ссылается на стек вашего модульного тестирования и затем заставьте несколько сборок мусора через GC.Collect(), затем используйте GC.WaitForPendingFinalizers().

Ваш метод finalize может устанавливать статический логический флаг, а затем ваш модульный тест может утверждать, что это правда.

Я бы поставил под вопрос утилизацию без дальнейших объяснений, но это, вероятно, самый простой способ доказать отсутствие оборванных ссылок в единичном тесте.

+0

В настоящее время я использую WeakReference к объекту, за которым следует GC.Collect/WFPF, тогда утверждают, что ссылка имеет значение null, чтобы сообщить мне, если она была очищена. Я делаю это как часть единичного теста, чтобы убедиться, что мой API не вызывает утечек.Но, как часть вывода «assert», я хотел бы распечатать, какие объекты поддерживают его, чтобы спасти меня, прыгая в профилировщик. –

+0

Я серьезно сомневаюсь, что это возможно в автоматическом режиме без огромного объема работы, чтобы разоблачить функциональность SOS самостоятельно, если кто-то из MS не сделал это уже. Я бы предположил, что лучше всего задуматься о написании чего-то, основанного на SOS, который автоматизирует весь поиск в одну команду, чтобы вы могли вызвать его из теста с ошибкой в ​​отладчике. Обратите внимание, что SOS не является автономным инструментом, он полностью зависит от присоединенного совместимого отладчика ... – ShuggyCoUk

+1

Если вы действительно хотите попытаться взломать его, посмотрите здесь: http://blogs.microsoft.co.il/ блоги/sasha/archive/2009/08/17/gc-helper-for-получения-live-instance-of-a-type-or-how-i-implement-gc-getalive -stances-lt-t-gt.aspx – ShuggyCoUk

1

Также помните, что .NET использует traced garbage collection, поэтому объекты, на которые ссылаются другие объекты - например, график объектов - по-прежнему будет очищен GC, если ваше приложение больше не ссылается ни на один из них; это намного умнее классической ссылки на подсчет алгоритмов сбора мусора pre -.NET. Это означает, что даже если вы найдете способ определить все ссылки на объект, некоторые из них могут не иметь значения и, возможно, не нужно их заботиться.

Это не отвечает непосредственно, как найти все ссылки на объект, но делает читателей осведомленными о ситуации, когда, когда вы найдете все ссылки с помощью инструмента или утилиты, некоторые вещи не нужны для большей фиксации в .NET - например классические круговые ссылки, и поэтому вам, возможно, придется искать некоторые гениальные способы узнать, что игнорировать при попытке исправить утечки памяти.

Это объяснение относится только к сценарию управляемого кода.

3

Профилировщик .NET использует profiling API для трассировки графика объектов. Вас могут особенно интересовать методы обратного вызова ObjectReferences и RootReferences, а также, возможно, ObjectAllocated. Первые два метода будут вызваны для покрытия всего графика живого объекта после каждого мусора, поэтому перехватывать их в одиночку достаточно, чтобы перестроить этот граф, а затем проанализировать его каким-либо образом.

This article объясняет, как соединить все части.

+2

статья отсутствует по этой ссылке – TankorSmash

Смежные вопросы