Как заставить сборщик мусора объекта вы не можете разыскивать? - PullRequest
9 голосов
/ 25 октября 2011

Мы используем EWS Managed API, который опрашивает MS Exchange на наличие новых почтовых сообщений через заданный интервал. При каждом вызове опроса (PullSubscription.GetEvents()) - Microsoft API не может правильно распорядиться NetworkStream и вызывает пропорциональное увеличение памяти. Ранее это обсуждалось здесь , но никогда не решалось. Используя ANTS Profiler, мы смогли определить, какие объекты постоянно растут в памяти, и изолировать проблему.

Теперь, когда проблема была изолирована - есть ли способ избавиться от NetworkStream, созданного во внешнем API, на который у нас нет ссылки? GC.Collect (), кажется, не располагает его, так как он все еще имеет активную ссылку. Что мы можем сделать, чтобы убрать свисающую ссылку? Есть ли какая-нибудь оболочка, которую мы можем использовать для принудительной очистки их глючного SDK?

Ответы [ 2 ]

6 голосов
/ 25 октября 2011

Невозможно заставить GC освободить память для объекта, на который есть ссылка!

Прежде всего, я бы предложил обратиться к самой Microsoft за помощью в устранении этой ошибки.

Во-вторых, вы?речь идет об «утилизации» или просто освобождении памяти?Это две совершенно разные вещи.(IDisposable pattern, finalizers).

В-третьих, можете ли вы просто разыменовать объект, ссылающийся на эти объекты?

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

0 голосов
/ 25 октября 2011

Самым простым способом было бы запустить часть, которая соединяет SDK с собственным AppDomain, и после того, как вы закончите, выгрузите AppDomain. Это приведет к освобождению всей памяти, выделенной в AppDomain.

Но вам нужно будет добавить некоторую работу в ваш проект, поскольку вы можете поменяться только с AppDomain объектом MarshalByRef или помеченным как serilizable.

Это также позволит вам контролировать количество памяти, используемой AppDomain. Таким образом, вы можете создать свой AppDomain, запустить в нем ошибочный SDK, и, если он достигнет особого предела потребления памяти, вы можете выгрузить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...