Link to home
Start Free TrialLog in
Avatar of PhilBird
PhilBird

asked on

TASPMTSObject not calling destructor

I'm building a TASPMTSObject to use from an ASP page.

In my testing I'm seeing DLLHost's memory consumption grow considerably (~2 MB per instance @ 1 instance per user) an not drop much (~200 K) when the session ends.
I've discovered that my Destructor which overrides .Destroy is not being called.

Is this normal? should I be overriding .ObjRelease instead?
I'm concerned that the object instances are not being destroyed let alone my private variables.


I'm using Delphi 6.0 w/ sp2 on W2k and IIS 5.0
I'm testing my object in a seperate instance of dllhost to isolate from iis thru component services.


thanks
Avatar of sfock
sfock

2 MB per instance is pretty large.

What are you storing there?

Are you storing anything in the session?

After overriding .ObjRelease  is a better idea than overriding the destructor destroy should be called althrogh this. But withing the MTS that does not have to happen immedeately.

Is your destructor never called?

Probably you can give as a little bit of sample code that we can get a better picture.
Avatar of PhilBird

ASKER

It stores 15 to 20 variants which are used to store strings and integers which are the state data for the users session in a dynamic array of variant not a variant array. The object itself is stored in the session.

it declares a private TADOConnection, TADOCommand and a TADODataSet to store the variants to the Database and retrieve previous values from a previous session for the same user. The plan is that it only goes to the DB when a value is requested that it does not already have.

The destructor never gets called. not even when MTS Ends the DLLHost process.

Currently I'm overriding .ObjRelease and calling destroy when .refCount < 1

the ASP page never calls release or destroy I just set the variant = nothing

the codes looks like:

TUsrData = Class(TASPMTSObject,IUSrData)
         Public
           Procedure SetData(Key,Value : OLEVariant);safecall;
           Procedure GetData(Key:OLEVariant; var Value:OLEVariant);SafeCall;
         Protected
           procedure Initialize;override;
           Destructor Destroy;override;
end;


Destructor Destroy;
begin

     for t:=1 to length(MyDynamicArray) do
         MyDynamicArray[t]:=unassigned
     MyDynamicArray:=nil;
     {ADO Command + Dataset are created and destroyed in .GetData}
     ADOConnection.Close;
     ADOConnection:=nil;
     Inherited;
end;
           

I Have a global.asa that sets the session key = nothing in the session_onEnd event.


Thanks
Shouldn't the destructor be public?
Perhaps, But Destroy is called by TComobject.ObjRelease therefore scope isn't really an issue. I've also confirmed that TComObject.Destroy is not being called as well.

Further testing by monitoring AllocMemSize and TheapStatus.TotalAllocated indicate all memory being allocated is being free'd when myObject.RefCount <= 0 as  it should. So I no longer think the destructor is the issue though it would have been nice if it worked. I'm now deallocating resources in my .ObjRelease function.

I belive the reason DllHost and my test program suck up ever increasing amounts of memory is due to the windows memory allocation scheme. I think it's designed to allocate new objects always at the end of previous objects even if they are free'd until it hits a threashold and does a compact of the heap. since the process address space is 2-4 GB that's why AllocMemSize reports that the amount of memory being allocated is not growing but Task manager shows the memory footprint growing.


So, This leaves me with a new twist. I Even though this may be correct I don't want my program to grow to 50+ MB when it only needs 2MB due to fast memory allocation. The Win32 api documents a "HeapCompact" function that may resolve my problem. However to use it I need the handle to the heap where my objects are being allocated. To get a handle to the heap I need to use the GetProcessHeaps function, but I can't get it to accept a pointer to a buffer in D6. The compiler wants a Cardinal but I can't seem to find a way to use a cardinal to pass a pointer to a buffer.

How do I get a buffer of Heap handles from GetProcessHeaps in D6 ???????????


Thanks
ASKER CERTIFIED SOLUTION
Avatar of sfock
sfock

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
PhilBird:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.