Уважаемые коллеги!
Есть COM-компонент (FWDBSet), использующийся для доступа к данным в SQLServer-е через комбинацию OLEDB-ADO (чистый OLEDB используется для получения сессии из пула коннектов и более быстрого создания и открытия Rowset-а, а для доступа к полям rowset-а используется ADORecordset). Компонент работает под dllhost-ом и для тестовых программ, описанных ниже, доступен как OutProc — компонент. Эти две тестовые программы создают и открывают по 100 DBSet-ов, одна из них написана на C++, вторая — на JS (на VBS эффект тот же). После исполнения программы на C++ размер памяти dllhost-а остается практически неизменным, после JS — вырастает на 25Мб. Исследования показали, что причиной роста является работа следующего куска кода (для краткости опущены проверки) в том месте, где создается ADORecordset через ADORecordsetConstruction:
var spSet;
var spIt;
for(i = 0; i < NumIter; i++)
{
spSet = spSrv.CreateDBSet("SELECT OID FROM TestCompoundAttr1", "1"); // создается новый экземпляр DBSet-а под dllhost-ом
spIt = spSet.GetIterator();
spIt.moveFirst();
delete spSet;
delete spIt;
}
Процедура создания Recordset-а через ADORecordsetConstruction — один в один из MSDN. Версия MDAC — 2.70.9001.0. Помогите пожалуйста советом, хотя бы в какую сторону копать!
Заранее благодарен.
Сергей.
Здравствуйте, Tom, Вы писали:
Tom>а можно вопрос ? Tom>1. Ты уверен, что под C++ клиентом обьект создаётся под DllHost ? А то вот эта строчка меня пугает: Tom>
Tom>SP::IFWSetPtr spSet = FWCreateDBSet(testAT); // создается новый экземпляр DBSet-а под dllhost-ом
Tom>
Уверен абсолютно. FWCreateDBSet — это просто служебная функция которая внутри создает объект на сервере.
Tom>2. Ты не пробовал воспользоваться BounceChecker ?
Пробовал. У меня стоит DevPartnerStudio. Показал нескольо ликов, например — в _bstr_t.Copy(), и еще несколько в системных библиотеках. Ничего близко связанного с моим вопросом не обнаружилось.
Здравствуйте, Tom, Вы писали:
Tom>1. а с чего ты тогда взял, что память утекает ?
Поскольку размер используемой памяти dllhost-а увеличивается на 25Мб (видно в TaskManager-е виндов), а если дать не 100 итераций а 150000 то памяти будет уже в районе гига, быстродействие системы падает раз в пять, после чего все умирает. Tom>2. Приведи всё таки код этой функции (которая создаёт обьект на сервере (dllhost))
FWSrvCore — это объект, сконфигурированный в COM+ (собственно dllhost — это COM+ приложение).
FWComponentCreator — Stateless component, предназначенный специально для создания объектов на сервере. Сам создается изнути COM+ приложения (в FWSrvCore).
Еще одно уточнение.
Если в тестовой программе убрать вызов GetFirst, где собственно осуществляется открытие ADORecordset-а, с памятью dllhost-а все становится хорошо, ничего не растет.
Я в принципе не могу понять, как ScriptHost может повлиять на размер памяти другого процесса, в то время как аналогичное приложение на C++ этого не делает. Что там, какая-то "интимная" связь между процессом ScriptHost-а и COM+ приложением?
не мог бы ты для успокаения моей души взглянуть а не увеличивается ли обьеё памяти при использовании C++ клиента у самого клиента и у COM+ приложения ? И ещё. Что значит фраза
FWSrvCore — это объект, сконфигурированный в COM+ (собственно dllhost — это COM+ приложение).
Здравствуйте, Tom, Вы писали:
Tom>не мог бы ты для успокаения моей души взглянуть а не увеличивается ли обьеё памяти при использовании C++ клиента у самого клиента и у COM+ приложения ? И ещё. Что значит фраза Tom>
Tom>FWSrvCore — это объект, сконфигурированный в COM+ (собственно dllhost — это COM+ приложение).
Объем dllhost-а при использовании С++ клиента увеличивается на 400кб (те же 100 итераций), но через некоторое время уменьшается (видимо освобождается пул коннектов и, возможно COM+ чего нибудь подчищает). Объем самого клиента честно говоря не проверял, и прямо сейчас проверить не смогу — идет повторная перекомпиляция под NuMega. Попробую с ней еще раз погонять.
Насчет COM+ — используется следующая структура. Как COM+ приложение сконфигурированы несколько компонентов (т. е. в COM+-е создано приложение, туда добавлены компоненты (включая FWSrvCore), выставлены нужные атрибуты.) У клиента есть указатель на FWSrvCore — этот объект гарантировано создается в контексте COM+ приложения (т. е. в процессе dllhost-а). Создание любого объекта осуществляется через него.
Первый шаг — у SrvCore запрашивается лекговесный компонент(ComponentCreator) — что-то типа специализированной фабрики классов. Этот компонент не сконфигурирован как COM+ и поэтому создается в контексте несконфигурированных компонентов но в процессе dllhost-а.
Второй шаг — у ComponentCreator-а вызывается метод CreateInstance, который создает нужный нам объект (в данном случае DBSet) опять же в контексте несконфигурированных компонентов но опять же в процессе dllhost-а.
КСВ>Здравствуйте, Tom, Вы писали:
Tom>>не мог бы ты для успокаения моей души взглянуть а не увеличивается ли обьеё памяти при использовании C++ клиента у самого клиента и у COM+ приложения ?
Объем памяти при использовании клиента С++ не увеличивается ни на клиенте ни на сервере.