?
Solved

TASPMTSObject not calling destructor

Posted on 2003-03-17
7
Medium Priority
?
373 Views
Last Modified: 2010-04-04
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
0
Comment
Question by:PhilBird
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 3

Expert Comment

by:sfock
ID: 8154730
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.
0
 

Author Comment

by:PhilBird
ID: 8154842
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
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 8158527
Shouldn't the destructor be public?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:PhilBird
ID: 8160437
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
0
 
LVL 3

Accepted Solution

by:
sfock earned 1500 total points
ID: 8161195
To access the buffer try the following:

type
  PHandle = ^Handle;
var
  myPhandle : PHandle;
  NumberOfHeaps, NumberOfValidHeaps: integer;
  ProcessHeaps : Cardinal;
begin
  NumberOfValidHeaps := GetProcessHeaps(NumberOfHeaps,ProcessHeaps );
  myPhandle  := PHandle(ProcessHeaps);
...
end;


_but_:
the MTS is managing his memory himself, so it sounds no good idea to try to manipupate this!

Have you checked out the pooling options in the MTS? probably they'll help.
0
 

Expert Comment

by:CleanupPing
ID: 9316744
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.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month12 days, 4 hours left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question