Утечка памяти объектов serveridentity, созданных прокси-серверами appdomain?

Проблема
TL; DR; Я вижу постоянную утечку объектов ServerIdentity для каждого создаваемого мной прозрачного прокси-объекта.

Я создаю домены приложений как механизм для изолирования выполнения некоторого стороннего кода и использую MarshalByRefObject и appDomain.CreateInstanceAndUnwrap() для создания прозрачного прокси для выполнения моего кода. Однако каждый маршалируемый экземпляр также создает соответствующий ServerIdentity, который, по-видимому, удерживается внутренним статическим классом.

Что я пробовал

  1. Выгрузка AppDomain через AppDomain.Unload(appdomain) отключает и очищает экземпляр AppDomain, но объекты ServerIdentity остаются и накапливаются.
  2. Вызов RemotingServies.Disconnect(marshalbyrefobject) вызывает исключение, поскольку он, по-видимому, не для обработки прозрачных прокси-серверов, поскольку вызывает эту ошибку: System.Runtime.Remoting.RemotingException: 'Cannot call disconnect on a proxy.'

Ближе всего к ответу я подошел к этому Сообщение блога, описывающему очень похожую проблему. Однако в их коде должен быть дополнительный контекст, которого мне не хватает.

dotMemory Скриншоты

Количество новых объектов увеличивается с каждым запросом, сборщик мусора не производитсяenter image description here

Пути хранения ключей экземпляра ServerIdentityenter image description here

Редактировать 1
Итак, я обнаружил, что вызвало исключение, упомянутое в пункте № 2. В основном вы не можете вызвать RemotingServices.Disconnect(proxyInstance) из основного домена приложения. Это должно быть сделано на реальном объекте экземпляра 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. Это действительно так. Может ли это подтвердить кто-нибудь, разбирающийся в этом вопросе?

Я думаю, что, возможно, испытываю то же самое, поскольку я вижу много экземпляров ServerIdentity, живущих за пределами точки, которую я больше не ожидал бы от них. Вы в конце концов узнали, была ли утечка памяти?

Bouke 24.05.2020 11:42

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

MplsAmigo 03.07.2020 02:43
3
2
374
0

Другие вопросы по теме