|
|
|
Fuji Deng
|
Hi,
I tried to use ArcSDEProvider92.dll (It’s file version number is 3.4.0.0), I encounted a memory leak problem. The test environment: 1. The application is running in WindowsXP with the latest updates. 2. The application is compiled by Visual Studio 2008 SP1. 3. SQL-Server 2008 And ArcSDE9.2 in Windows 2003 SP2 with almost the latest updates. 4. About ArcSDEProvider92.dll, I test both the file downloaded from website and compile by source codes. There’s the test sample codes at the end of this post. I set 2 breakpoints in the _tmain function, one is at the “for (int i = 0; i < 100; i++)”, the other one is at the “return 0;” The difference of memory usage between these 2 breakpoints is about 60 MB, that means there’re 60 MB memory not released. In each loop, there’re about 300 shapes be read, those shapes are simple polygons, each polygon contains about 5-10 points. I tried to release the all resources in the “for” loop, but it seems there’re still some memory not released. Do I miss something when try to release memory? Or is it the ArcSDEprovider92.dll issue? #include "stdafx.h" #include "string.h" #include <Windows.h> #include "Fdo/Connections/IConnection.h" #include "Fdo/Commands/CommandType.h" #include "Fdo/Commands/ICommand.h" #include "Fdo/Commands/IFeatureCommand.h" #include "Fdo/Commands/Feature/ISelect.h" #include "Geometry/Fgf/Factory.h" #include "Common/Array.h" typedef FdoIConnection* (*CreateConnectionProc)(); #ifdef _WIN32 #ifndef ARCSDEPROVIDER_EXPORTS #define FDOSDE_API __declspec(dllexport) #else #define FDOSDE_API __declspec(dllimport) #endif #endif class ArcSDELoaderLibrary { private: HMODULE m_hArcSDE; public: ArcSDELoaderLibrary() { m_hArcSDE = NULL; try { HMODULE hmod = ::LoadLibraryW(L"sde.dll"); if (hmod != NULL) { ::FreeLibrary(hmod); m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider92.dll"); // in case load ArcSDEProvider92.dll fails try to load 91 if (m_hArcSDE == NULL) m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll"); } else m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll"); } catch(...){} } HMODULE GetLibraryHandle() { return m_hArcSDE; } ~ArcSDELoaderLibrary() { try { if (m_hArcSDE != NULL) ::FreeLibrary(m_hArcSDE); } catch(...){} } }; static ArcSDELoaderLibrary arcSDEloader; // external access to connection for client services extern "C" FDOSDE_API FdoIConnection* CreateConnection () { CreateConnectionProc procCreateConn; HMODULE hArc = arcSDEloader.GetLibraryHandle(); if (hArc != NULL) { procCreateConn = (CreateConnectionProc)::GetProcAddress (hArc, "CreateConnection"); if (procCreateConn != NULL) return procCreateConn(); } return NULL; } int _tmain(int argc, _TCHAR* argv[]) { FdoIConnection* connection = CreateConnection(); FdoString* connectionString = L"Server=serverIP;Instance=5151;Username=username;Password=password;Datastore=datastore"; FdoFgfGeometryFactory* factory = FdoFgfGeometryFactory::GetInstance(); connection->SetConnectionString(connectionString); FdoConnectionState state = connection->Open(); for (int i = 0; i < 100; i++) { FdoISelect* command = (FdoISelect*)connection->CreateCommand(FdoCommandType_Select); command->SetFeatureClassName(L"TableName"); command->SetFilter(L"Shape ENVELOPEINTERSECTS GeomFromText(‘Wkt of the specify extent.')"); FdoIFeatureReader* reader = command->Execute(); while (reader->ReadNext()) { FdoByteArray* ba = reader->GetGeometry(L"ShapeColumnName"); FdoIGeometry* geometry = factory->CreateGeometryFromFgf(ba); ba->Release(); geometry->Release(); } reader->Release(); command->Release(); } connection->Release(); factory->Release(); return 0; } |
||||||||||||||||
|
Jackie Ng
|
I see two things here:
1 - Is there any reason why you have written your own library loader? The IConnectionManager already achieves this purpose of obtaining FdoIConnection pointers. You can obtain a pointer to the IConnectionManager by using FdoFeatureAccessManager::GetConnectionManager() This code should let you obtain an ArcSDE connection pointer. FdoPtr<IConnectionManager> connMgr = FdoFeatureAccessManager::GetConnectionManager(); FdoPtr<FdoIConnection> arcSdeConn = connMgr->CreateConnection(L"OSGeo.ArcSDE"); 2 - Try wrapping your pointers to Fdo classes within a FdoPtr smart pointer template. That will auto-release your pointers when the smart pointer goes out of scope. - Jackie
|
||||
|
Fuji Deng
|
Jackie Ng, Thanks for your suggestion. After I change the testing codes by following your suggestion. I do the same testing, there’s still about 60MB memory not released when application running to “return 0” line. Is there any advice? Following are the testing codes: #include "stdafx.h" #include "string.h" #include <Windows.h> #include "Fdo/Connections/IConnection.h" #include "Fdo/ClientServices/FeatureAccessManager.h" #include "Fdo/ClientServices/ConnectionManager.h" #include "Fdo/Commands/CommandType.h" #include "Fdo/Commands/ICommand.h" #include "Fdo/Commands/IFeatureCommand.h" #include "Fdo/Commands/Feature/ISelect.h" #include "Geometry/Fgf/Factory.h" #include "Common/Array.h" #include "Common/Ptr.h" void Test() { FdoPtr<FdoConnectionManager> connMgr = (FdoConnectionManager*)FdoFeatureAccessManager::GetConnectionManager(); FdoPtr<FdoIConnection> connection = connMgr->CreateConnection(L"OSGeo.ArcSDE"); FdoPtr<FdoFgfGeometryFactory> factory = FdoFgfGeometryFactory::GetInstance(); connection->SetConnectionString(L"Server=serverIP;Instance=5151;Username=username;Password=password;Datastore=datastore"); FdoConnectionState state = connection->Open(); for (int i = 0; i < 100; i++) { FdoPtr<FdoISelect> command = (FdoISelect*)connection->CreateCommand(FdoCommandType_Select); command->SetFeatureClassName(L"TableName"); command->SetFilter(L"Wkt of the specify extent"); FdoPtr<FdoIFeatureReader> reader = command->Execute(); while (reader->ReadNext()) { FdoPtr<FdoByteArray> ba = reader->GetGeometry(L"ShapeColumnName"); FdoPtr<FdoIGeometry> geometry = factory->CreateGeometryFromFgf(ba); } } } int _tmain(int argc, _TCHAR* argv[]) { Test(); return 0; } Fuji Deng
|
||||||||||||||||
|
Dan Stoica
|
Hi,
Did you try without the filter? Is it still leaking? Thanks, Dan. -----Original Message----- From: [hidden email] [mailto:[hidden email]] On Behalf Of Fuji Deng Sent: Monday, June 01, 2009 1:31 AM To: [hidden email] Subject: Re: [fdo-users] Memory problem with ArcSDEProvider92.dll Jackie Ng, Thanks for your suggestion. After I change the testing codes by following your suggestion. I do the same testing, there’s still about 60MB memory not released when application running to “return 0” line. Is there any advice? Following are the testing codes: #include "stdafx.h" #include "string.h" #include <Windows.h> #include "Fdo/Connections/IConnection.h" #include "Fdo/ClientServices/FeatureAccessManager.h" #include "Fdo/ClientServices/ConnectionManager.h" #include "Fdo/Commands/CommandType.h" #include "Fdo/Commands/ICommand.h" #include "Fdo/Commands/IFeatureCommand.h" #include "Fdo/Commands/Feature/ISelect.h" #include "Geometry/Fgf/Factory.h" #include "Common/Array.h" #include "Common/Ptr.h" void Test() { FdoPtr<FdoConnectionManager> connMgr = (FdoConnectionManager*)FdoFeatureAccessManager::GetConnectionManager(); FdoPtr<FdoIConnection> connection = connMgr->CreateConnection(L"OSGeo.ArcSDE"); FdoPtr<FdoFgfGeometryFactory> factory = FdoFgfGeometryFactory::GetInstance(); connection->SetConnectionString(L"Server=serverIP;Instance=5151;Username=username;Password=password;Datastore=datastore"); FdoConnectionState state = connection->Open(); for (int i = 0; i < 100; i++) { FdoPtr<FdoISelect> command = (FdoISelect*)connection->CreateCommand(FdoCommandType_Select); command->SetFeatureClassName(L"TableName"); command->SetFilter(L"Wkt of the specify extent"); FdoPtr<FdoIFeatureReader> reader = command->Execute(); while (reader->ReadNext()) { FdoPtr<FdoByteArray> ba = reader->GetGeometry(L"ShapeColumnName"); FdoPtr<FdoIGeometry> geometry = factory->CreateGeometryFromFgf(ba); } } } int _tmain(int argc, _TCHAR* argv[]) { Test(); return 0; } Fuji Deng Jackie Ng wrote: > > I see two things here: > > 1 - Is there any reason why you have written your own library loader? The > IConnectionManager already achieves this purpose of obtaining > FdoIConnection pointers. You can obtain a pointer to the > IConnectionManager by using > FdoFeatureAccessManager::GetConnectionManager() > > This code should let you obtain an ArcSDE connection pointer. > > FdoPtr<IConnectionManager> connMgr = > FdoFeatureAccessManager::GetConnectionManager(); > FdoPtr<FdoIConnection> arcSdeConn = > connMgr->CreateConnection(L"OSGeo.ArcSDE"); > > 2 - Try wrapping your pointers to Fdo classes within a FdoPtr smart > pointer template. That will auto-release your pointers when the smart > pointer goes out of scope. > > - Jackie > > > Fuji Deng wrote: >> >> Hi, >> I tried to use ArcSDEProvider92.dll (It’s file version number is >> 3.4.0.0), I encounted a memory leak problem. >> The test environment: >> 1. The application is running in WindowsXP with the latest updates. >> 2. The application is compiled by Visual Studio 2008 SP1. >> 3. SQL-Server 2008 And ArcSDE9.2 in Windows 2003 SP2 with almost the >> latest updates. >> 4. About ArcSDEProvider92.dll, I test both the file downloaded from >> website and compile by source codes. >> >> There’s the test sample codes at the end of this post. >> I set 2 breakpoints in the _tmain function, one is at the “for (int i = >> 0; i < 100; i++)”, the other one is at the “return 0;” The difference of >> memory usage between these 2 breakpoints is about 60 MB, that means >> there’re 60 MB memory not released. >> In each loop, there’re about 300 shapes be read, those shapes are simple >> polygons, each polygon contains about 5-10 points. >> I tried to release the all resources in the “for” loop, but it seems >> there’re still some memory not released. >> >> Do I miss something when try to release memory? Or is it the >> ArcSDEprovider92.dll issue? >> >> #include "stdafx.h" >> #include "string.h" >> #include <Windows.h> >> #include "Fdo/Connections/IConnection.h" >> #include "Fdo/Commands/CommandType.h" >> #include "Fdo/Commands/ICommand.h" >> #include "Fdo/Commands/IFeatureCommand.h" >> #include "Fdo/Commands/Feature/ISelect.h" >> #include "Geometry/Fgf/Factory.h" >> #include "Common/Array.h" >> >> typedef FdoIConnection* (*CreateConnectionProc)(); >> >> #ifdef _WIN32 >> >> #ifndef ARCSDEPROVIDER_EXPORTS >> #define FDOSDE_API __declspec(dllexport) >> #else >> #define FDOSDE_API __declspec(dllimport) >> #endif >> #endif >> >> class ArcSDELoaderLibrary >> { >> private: >> HMODULE m_hArcSDE; >> >> public: >> ArcSDELoaderLibrary() >> { >> m_hArcSDE = NULL; >> try >> { >> HMODULE hmod = ::LoadLibraryW(L"sde.dll"); >> if (hmod != NULL) >> { >> ::FreeLibrary(hmod); >> m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider92.dll"); >> // in case load ArcSDEProvider92.dll fails try to load 91 >> if (m_hArcSDE == NULL) >> m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll"); >> } >> else >> m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll"); >> } >> catch(...){} >> } >> HMODULE GetLibraryHandle() >> { >> return m_hArcSDE; >> } >> ~ArcSDELoaderLibrary() >> { >> try >> { >> if (m_hArcSDE != NULL) >> ::FreeLibrary(m_hArcSDE); >> } >> catch(...){} >> } >> }; >> >> static ArcSDELoaderLibrary arcSDEloader; >> // external access to connection for client services >> extern "C" FDOSDE_API FdoIConnection* CreateConnection () >> { >> CreateConnectionProc procCreateConn; >> HMODULE hArc = arcSDEloader.GetLibraryHandle(); >> >> if (hArc != NULL) >> { >> procCreateConn = (CreateConnectionProc)::GetProcAddress (hArc, >> "CreateConnection"); >> if (procCreateConn != NULL) >> return procCreateConn(); >> } >> return NULL; >> } >> >> >> int _tmain(int argc, _TCHAR* argv[]) >> { >> FdoIConnection* connection = CreateConnection(); >> FdoString* connectionString = >> L"Server=serverIP;Instance=5151;Username=username;Password=password;Datastore=datastore"; >> FdoFgfGeometryFactory* factory = >> FdoFgfGeometryFactory::GetInstance(); >> connection->SetConnectionString(connectionString); >> FdoConnectionState state = connection->Open(); >> >> for (int i = 0; i < 100; i++) >> { >> FdoISelect* command = >> (FdoISelect*)connection->CreateCommand(FdoCommandType_Select); >> command->SetFeatureClassName(L"TableName"); >> command->SetFilter(L"Shape ENVELOPEINTERSECTS >> GeomFromText(‘Wkt of the specify extent.')"); >> FdoIFeatureReader* reader = command->Execute(); >> >> while (reader->ReadNext()) >> { >> FdoByteArray* ba = >> reader->GetGeometry(L"ShapeColumnName"); >> FdoIGeometry* geometry = >> factory->CreateGeometryFromFgf(ba); >> ba->Release(); >> geometry->Release(); >> } >> reader->Release(); >> command->Release(); >> } >> >> connection->Release(); >> factory->Release(); >> >> return 0; >> } >> >> > > View this message in context: http://n2.nabble.com/Memory-problem-with-ArcSDEProvider92.dll-tp3003984p3004741.html Sent from the FDO Users mailing list archive at Nabble.com. _______________________________________________ fdo-users mailing list [hidden email] http://lists.osgeo.org/mailman/listinfo/fdo-users _______________________________________________ fdo-users mailing list [hidden email] http://lists.osgeo.org/mailman/listinfo/fdo-users |
||||||||||||||||
|
Fuji Deng
|
Dan, Thanks for your reply. I try testing without the filter; it’s still leaking almost the same size of memory. After the “Connection->Open()” statement execute, the memory usage is: “Mem Usage” is 14,524K “VM Size” is 10,660K When the application runs to “return 0” statement, Following is the memory usage: 1 - Before remove filter: “Mem Usage” is 76,820K “VM Size” is 72,496K about 300 records read for one query 2 - After remove filter: “Mem Usage” is 76,840K “VM Size” is 72,600K about 8,000 records read for one query I do another test also. I keep the filter, and remove the “while (reader->ReadNext())” and its block. When the application runs to “return 0” statement, the memory usage is: “Mem Usage” is 76,956K “VM Size” is 72,632K Any suggestions? Thanks! Fuji Deng
|
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |