2009-02-24 5 views
0

Унаследованные приложения C++ с иногда печально известными проблемами утечки памяти необходимо вызывать из приложения Windows на базе Windows. .Net время сбора мусора не поддается определению, и когда-то объект C++ уничтожается или не уничтожается «вовремя», создавая непредсказуемые результаты и обычно разбивая веб-приложение C#. Каков наилучший способ скопировать объекты C++ в стек сбора мусора как можно чаще, но не так часто, как удалить ссылку .Net на COM-объект. Имейте в виду, что объекты COM могут порождать под-объекты, поэтому подсчет ссылок .Net объектов COM может меняться только с помощью вызова функции и не обязательно для создания экземпляра.Как управлять COM-объектами в. Net Web Application

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

Мне пришлось решить эту проблему с использованием .Net 1.1 пару лет назад. Удивление, если у кого-то было мое решение или лучшее. Это не ASP.NET. Это DLL .Net.

Конечный результат не был полностью удовлетворительным, и веб-сервер разбился каждые несколько месяцев.

+0

Я склонен согласиться с тем, что это сложно или невозможно с .Net 1.1, но у нас есть возможность перейти на .Net 2.0. Является ли это по своей сути лучше или есть новые функции в этом, которые помогут? – ssorrrell

ответ

1

Вы спрашиваете: «Как наилучшим образом удалять объекты C++ в стек сбора мусора как можно чаще», но объекты C++ никогда не собираются с мусором. Возможно, посмотрите на это так ...

У вас есть процесс, который создает кучу C++-объектов. Некоторые из этих объектов C++ реализуют COM-объекты, поэтому их время жизни управляется с помощью AddRef/Release. Некоторые из этих COM-объектов импортируются в мир .NET и обертываются RCW (оболочка, вызываемая вызовом). Только RCW является объектом .NET и входит в кучу мусора.

Без какого-либо вмешательства со стороны RCW в конечном итоге будет GC'd, и когда это произойдет, он сделает Release против своего базового COM-объекта. Если вы хотите, чтобы немедленно освободить объект COM, не дожидаясь GC, вы можете позвонить ...

System.Runtime.InteropServices.Marshal.ReleaseComObject

... или даже FinalReleaseComObject, если вы уверены, что это что ты хочешь.

Чтобы вернуться к вашему вопросу: вы хотите знать, как удалить объекты C++, не отбрасывая ссылку .NET на свой COM-объект. Так как объекты C++ не существуют в куче .NET, этого невозможно достичь напрямую. Вы можете выставить метод из вашего объекта COM, который удаляет все его объекты C++, и просто вызывать это из вашего .NET-кода. Но я думаю, если бы ваш объект COM мог идентифицировать все пропущенные объекты C++, которые вы уже делали бы.

Надеюсь, я объяснил, почему нет способа достичь того, что вы предлагаете в своем вопросе, но есть множество инструментов, которые помогут вам найти и исправить утечки памяти. Я предлагаю использовать такой инструмент, как LeakDiag (поиск StackOverflow для него), чтобы узнать, где протекает ваш код на C++.

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

0

Создайте приложение COM + и поместите классы COM, которые вы используете внутри этого приложения. Таким образом, все COM-объекты создаются в отдельном процессе.Вы можете периодически выпускать все COM-объекты и просто перезапускать процесс приложения COM +.

+0

Сохранение COM-объектов в отдельном процессе - интересная идея. Я не уверен, что это возможно. – ssorrrell

+0

Вот как работает COM +. Вы берете свой COM-сервер в процессе и попросите COM + создать «приложение COM +», которое на самом деле является просто внеочередным COM +-сервером с одинаковой функциональностью. И вне процесса означает, что все объекты находятся в отдельном процессе. – sharptooth

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

  • Нет связанных вопросов^_^