Com object Garbase disposal

  • Thread starter Thread starter Matt MacDonald
  • Start date Start date
M

Matt MacDonald

Hi all,
I'm working on a web app that uses a client-designed com dll to access a
database, do calculations, etc. When I create a new object from this dll it
takes up a lot of memory, so I want to get rid of it asap. My code looks
similar to the following"

Dim obj as new COMobj
.....
Do Processing
......
obj = Nothing
gc.collect

As you can see, I'm setting the object that I create to nothing and calling
the garbage collector, which, in my mind, should release the allocated
memory. While watching the task manager however, this does not appear to be
happening until about 20 minutes afterwards, around the time that the web
session would expire. How can I force the memory for this object to be
released. Once again, this is not a .NET assembly, this is a COM dll.

Any help would be very appreciated.

Thanks in advance,
Matt
 
As you can see, I'm setting the object that I create to nothing and calling
the garbage collector, which, in my mind, should release the allocated
memory. While watching the task manager however, this does not appear to be
happening until about 20 minutes afterwards, around the time that the web
session would expire. How can I force the memory for this object to be
released. Once again, this is not a .NET assembly, this is a COM dll.

You can try calling

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)

and I would recommend that you remove the GC.Collect call.


Mattias
 
I tried it all different ways, including the releasecomobject(obj). The
call completes fine, but the memory usage of aspnet_wp.exe does not
decrease. The only way I can get it to go back down is to restart IIS.
 
Matt MacDonald said:
Hi all,
I'm working on a web app that uses a client-designed com dll to access a
database, do calculations, etc. When I create a new object from this dll
it takes up a lot of memory, so I want to get rid of it asap. My code
looks similar to the following"

Dim obj as new COMobj
....
Do Processing
.....
obj = Nothing
gc.collect

As you can see, I'm setting the object that I create to nothing and
calling the garbage collector, which, in my mind, should release the
allocated memory. While watching the task manager however, this does not
appear to be happening until about 20 minutes afterwards, around the time
that the web session would expire. How can I force the memory for this
object to be released. Once again, this is not a .NET assembly, this is a
COM dll.

Any help would be very appreciated.

Thanks in advance,
Matt

The GC cannot release unmanaged memory. Sure you can call ReleaseComObject
to get rid of the COM object allocated memory (unmanaged), but the memory
taken by the DLL itself won't be freed until the application unloads.

Willy.
 
Matt,
I tried it all different ways, including the releasecomobject(obj). The
call completes fine, but the memory usage of aspnet_wp.exe does not
decrease. The only way I can get it to go back down is to restart IIS.

Well the DLL itself is still loaded, including any shared resources it
may hold. It will stay loaded until IIS calls CoFreeUnusedLibraries
(if it ever does, I don't know) or the proess is closed.



Mattias
 
What I'm noticing is that it doesn't matter how many times i instantiate the
dll, it seems to raise the memory used by aspnet_wp only if it goes higher
than it has previously been. for example

start at 10 MB
launch app and instantiate 1 object - up to 14MB
kill app - still at 14MB
launch app again and instantiate 1 object - still at 14MB

So I guess what I really need to know then, is how to free the memory
reserved by aspnet_wp that is not being used?
 
Mattias Sjögren said:
Matt,


Well the DLL itself is still loaded, including any shared resources it
may hold. It will stay loaded until IIS calls CoFreeUnusedLibraries
(if it ever does, I don't know) or the proess is closed.

Hmm.. IIS does not load these DLL's, the asp.net worker process does, and
this one doesn't call CoFreeUnusedLibraries.

Willy.
 
Matt MacDonald said:
What I'm noticing is that it doesn't matter how many times i instantiate
the dll, it seems to raise the memory used by aspnet_wp only if it goes
higher than it has previously been. for example

start at 10 MB
launch app and instantiate 1 object - up to 14MB
kill app - still at 14MB
launch app again and instantiate 1 object - still at 14MB


I don't get this, "kill app - still at 14MB", how can an application that
was killed still use memory?

Willy.
 
The problem is that IIS defaults to never releasing DLLs from memory until
IIS is stopped. You can change this to be at least session specific by
making the COM object a Session reference. This way the COM interface can
be handled by the ASP runtime directly, with the cleanup occurring when the
COM object's last reference is released. The other issue I suspect your COM
Object has is that it's "Apartment Single Threaded." I'm basing this on the
fact that significant amounts of memory are being consumed for each
reference. If you can, you need to get the developer of this object to
switch to "Apartment Multi-Threaded" and only the data segment of the object
will be duplicated into each session. The first session will of course get
the code as well, but that will be shared system wide.

In classic ASP, you can add a line to the global.asa file along the lines of

<OBJECT RUNAT=SERVER SCOPE=Session ID=ShortName
PROGID="ComObject.ComInterface"></OBJECT>

I don't know what the equivalent in ASP.NET's configuration file is,
however.

Mike Ober.
 
Yeah, that's what we're doing now. Making the COM Object a session
reference. The problem is that that means we still have to wait the 20
minutes (session timeout) for the memory to be released. If the site gets
100 hits in that 20 minutes, we are going to run out of memory fast.
 
But the application is NOT hosted in IIS, it's hosted in the asp.net worker
process.
So the question remains, what is meant with kill the application?

Willy.
 
I still don't get it, what did you mean with :
I "kill app - still at 14MB",
do you mean that it starts at 14 MB after being killed or what? (here I
guess you killed aspnet_wp.exe, right?).

Did you actualy measured anything using perfmon, or a memory profiler? Does
the memory consumption grows when the site get's hit continiously?

Note that while the COM dll get's loaded with the creation of the first
instance of an object, it's only loaded once irrespective the number of
calls, so this is not the cause of any extra memory consumption.

Willy.
 
Sorry, I should have been clearer. By Kill the App, I just mean that I
close out of IE. So the app isn't really killed. But when I open another
IE, a new session is created, but the memory allocation isn't increased.

Thanks,
Matt
 
Back
Top