0

I have a webservice created with RemObjects SDK over Delphi XE and a function published that to do his works needs to use com objects (Specifically Ado connection to database using DMO). I have detected that when I call this function a lot of times the memory that uses the webservice increases dramatically.

The cause of the memory leak is that the memory that is reserved for the com objects is not released never.

What I have to do to fix that?

Thanks

Code:

constructor TA.Create;
begin
    inherited Create;
    oServer := CoSQLServer.Create;
end;

destructor TA.Destroy;
begin
   oServer := nil;
end;

Declaration

class function CoSQLServer.Create: _SQLServer;
begin
    Result := CreateComObject(CLASS_SQLServer) as _SQLServer;
end;
  • How are you measuring the memory use? And the solution seems clear - you need to release the COM objects you're not using any longer (or simply don't create them all; create them once and re-use them). – Ken White Dec 28 '12 at 17:09
  • Every call on the webservice is an independent thread. How I realase COM Objects? I tried to set the objects to nil and it doesn't work –  Dec 28 '12 at 17:12
  • I can't answer that, because there's no code in your question to use to determine the answer. – Ken White Dec 28 '12 at 17:26
  • What is `CoSQLServer`? I know it's a COM object, but what is the COM class it points to? – Ken White Dec 28 '12 at 17:31
  • The COM Object of import Microsoft SQLDMO Object Library –  Dec 28 '12 at 17:37
  • According to the documentation, setting it to `nil` should work. You didn't answer my first question, though - how are you measuring memory use? – Ken White Dec 28 '12 at 17:41
  • Using window task administrator. If I comment the construction of the COM Object the memory don't increases –  Dec 28 '12 at 17:48
  • Of course it doesn't increase if you don't create it; you don't need the memory then. I think you're chasing a non-problem here, because you don't know how Delphi's memory manager works. It allocates the memory when you create something, but doesn't release it immediately because it assumes you'll create something again; when you do, it reuses that previous memory block again if it can. As long as you're not creating a huge number of objects where the memory gets outrageously large, you should be fine. Creating, using, and then setting to nil should work fine for you. – Ken White Dec 28 '12 at 17:55
  • The problem is that every call to the webservice is a Thread. After execute the test during an hour the system runs out of memory –  Dec 28 '12 at 18:03
  • That's the first time you've mentioned either of those things (threads and running out of memory) in this entire thread including your question itself. "Increases dramatically" is not the same as "keeps growing until the system runs out of memory". – Ken White Dec 28 '12 at 18:04
  • Every call to a webservice always is a thread –  Dec 28 '12 at 18:06
  • Use AQTIME and you will be able to find out what was not freed and then, you can fix it. This question is not answerable because you have not shown what leaks, because you don't know for sure what leaks. You have told us that you know, but not how you know, which in the end means, you don't know. – Warren P Dec 28 '12 at 18:25
  • Thanks for the AQTIME suggestion I will try it. And well... I know that the problem is in the memory of the COM Object because using a intensive test against the webservice that creates the object and destroys it without do anything more the memory increases constantly. Without the object the same test and the memory maintains constant –  Dec 28 '12 at 23:11

1 Answers1

1

In the code you show, the only thing that we can criticise is your destructor:

destructor TA.Destroy;
begin
  oServer := nil;
end;

Assigning nil to oServer is rather pointless (albeit harmless) since that will happen automatically.

But what is missing here is a call to the inherited destructor. So, your destructor should look like this:

destructor TA.Destroy;
begin
  oServer := nil;
  inherited;
end;

Now, if you decided to remove the finalization of oServer then you could simply remove the destructor from your class and rely on that of the base class.

However, you do appear to be measuring your memory leak with an invalid tool. You can't measure memory leaks with task manager. Use the FastMM leak detector.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490