Задача
TLDR; Я наблюдаю постоянную утечку ServerIdentity
объектов для каждого прозрачного прокси-объекта, который я создаю.
Я создаю домены приложений в качестве механизма для песочницы для выполнения некоторых сторонних кодов и использую MarshalByRefObject
и appDomain.CreateInstanceAndUnwrap()
для генерации прозрачного прокси для выполнения моего кода. Однако каждый экземпляр, который я маршал, также создает соответствующий ServerIdentity
, который, очевидно, поддерживается внутренним статическим классом.
Что я пробовал
- Выгрузка
AppDomain
через AppDomain.Unload(appdomain)
отключает и очищает экземпляр AppDomain
, но объекты ServerIdentity
остаются и накапливаются.
- При вызове
RemotingServies.Disconnect(marshalbyrefobject)
выдается исключение, так как оно, очевидно, не для обработки прозрачных прокси, поскольку выдает эту ошибку: System.Runtime.Remoting.RemotingException: 'Cannot call disconnect on a proxy.'
Самым близким, к которому я пришел, чтобы найти ответ на этот вопрос, был пост в блоге , описывающий очень похожую проблему. Однако в их коде должен быть дополнительный контекст, который мне не хватает.
dotMemory Скриншоты
Количество новых объектов увеличивается с каждым запросом, мусор не собирается
Пути хранения ключей экземпляра ServerIdentity
Редактировать 1
Итак, я обнаружил, что вызывало исключение, упомянутое в пуле номер 2. По сути, вы не можете позвонить RemotingServices.Disconnect(proxyInstance)
из основного AppDomain. Это должно быть сделано на реальном MarshalByRefObject
объекте экземпляра, созданном во вторичном AppDomain
. По сути, я создал свою собственную абстрактную реализацию MarshalByRefObject
примерно так. Я подтвердил, что Disconnect()
вызывается для каждого экземпляра с маршалингом.
public abstract class SandboxedInstance : MarshalByRefObject
{
public sealed override object InitializeLifetimeService()
{
// This override implementation ensures the lifetime of this object until Dispose() is called.
return null;
}
/// <summary>
/// Method called internally when containing Sandbox is disposed, automatically disposing this object.
/// </summary>
internal void Disconnect()
{
RemotingServices.Disconnect(this);
}
}
Однако это не решило мою проблему. Объекты ServerIdentity
, кажется, все еще существуют, несмотря на то, что RemotingServies.Disconnect(marshalbyrefobject)
успешно вызывается. Есть ли кто-нибудь, кто понимает, что происходит? Я могу найти очень мало документации по этому вопросу.
Редактировать 2
Есть ли кто-нибудь, кто может подтвердить эту теорию? Я читал упоминания о том, что некоторые удаленные объекты живут за пределами Disconnect()
, но в конечном итоге очищаются. Основываясь на этой теории, я запустил dotMemory и наблюдал, очищались ли объекты ServerIdentity с течением времени, особенно те, которые были сохранены с помощью Lease
. Это на самом деле, похоже, так. Может ли кто-нибудь со знанием этого вопроса подтвердить это?