System.OutOfMemoryException

D

Dmitry Akselrod

Hello everyone,

I am working in Visual Studio 2002 (I wonder if that's part of the problem).
The reason I am working in 2002 is to keep everything compatible with .NET
Framework 1.0. I wrote a small COM DLL in unmanaged C++. I am using the
DLL in a managed VB.NET application. The DLL basically just reads the
properties of compound structured storage files. The DLL uses ATL for some
String functions. The VB.NET application uses the information passed by the
COM DLL to communicate with an MS Access database.

The VB.NET program works just fine for a few hours, indexing the properties
of tons of structured storage files. After a few hours, it craps out with
the following error messages:

System.OutOfMemoryException: Creating an instance of the COM component with
CLSID {375D546A-4313-4CD4-9E3C-F71095F100F8} from the IClassFactory failed
due to the following error: 8007000e.

I checked the DLL and I don't believe that anything is being left on the
heap. Every NEW has an associated DELETE call. I believe that COM objects
associated with structured storage are being properly released, since the
files I am indexing do not remain locked. I noticed that if you don't
release a COM pointer or one doesn't go out of scope, Windows keeps the
structured storage file locked.

I am not entirely sure how I can troubleshoot this, especially since it
takes hours for the issue to occur. Is this likely a memory leak? Could
this be an issue with Visual Studio 2002? Is it on the .NET framework side
or on the unmanaged C++ side (ATL). If I compile the DLL is VS2005, but
still use VS2002 for the .NET app, would that make a difference? I am
really stuck here and would appreciate some advice on how to proceed.

Thanks in advance!
 
B

Brian Muth

Sanity question: Are you calling Marshal.ReleaseCOMObject() in your
client code?

Brian
 
D

Dmitry Akselrod

I am not actually. I thought that a proper COM DLL cleared itself out once
it went ouf scope. I just added the COM Reference to my project and use
something like below...

dim msg as New MSGParserLib.MSGFile()
msg.Open(fileName)
....
do stuff
....
msg.close

Should I be calling Marshal.ReleaseCOMObject()?

thanks,
dmitry
 
B

Brian Muth

Dmitry Akselrod said:
I am not actually. I thought that a proper COM DLL cleared itself
out once it went ouf scope. I just added the COM Reference to my
project and use something like below...

dim msg as New MSGParserLib.MSGFile()
msg.Open(fileName)
....
do stuff
....
msg.close

Should I be calling Marshal.ReleaseCOMObject()?

Yes. It's there for a purpose. Otherwise the .NET garbage collector
hangs on to the COM object until God-knows-when. Whenever you have
finished with a COM object, explicitly release it using this method
call. See if that helps.
 
D

Dmitry Akselrod

Thanks, I tried that using that method after closing the object I create
from my DLL. It didn't make any difference, the program still stopped
responding and forced a bunch of those messages after about 4 hours this
time.

thanks,
dmitry
 
D

Dmitry Akselrod

Thanks, so you think that the memory leak is likely happening on the .NET
side? Maybe I can rewrite my code to have just one instance of the COM DLL
in my .NET code and keep reusing it. My hunch is that constant creation
and destruction of COM objects in .NET 1.0 is probably buggy. By constant,
I mean at least 45,000 times.

Thanks,
Dmitry
 
C

Cor Ligthert[MVP]

Dmitry,

I've never heard that a Net class as its unmanaged resources where disposed
did not finalize automaticly by the GC.

However, you have at least to be sure that there are no unmanaged resources
like Com compontents are leaking.

Have a look at dispose unmanaged resources;

Keywords
Components
Dispose

Cor
 
B

Brian Muth

It's a good point. It's quite easy to leak memory in your COM server,
particularly if you are working with BSTR'ings.

Why don't you run Performance Monitor, watching the Private Bytes
counter of your task? That's a pretty easy way if confirming your
memory leak. If you are suspicous about your COM server, post your
interface definition, and perhaps some code implementation to show
your your programming style. It's sometimes quite trivial for others
here to pick up bad habits, mistakes, etc.
 
D

Dmitry Akselrod

I made a modification to the .NET client. I basically created a global
instance of the COM object and I keep reusing it. So far the program has
been running steadily and has parsed over 180,000 files. No errors yet. I
don't think that .NET 1.0 liked me creating so many instances of a COM
object, even though they were destroyed.

I definitely have some memory issues, but I don't think that they are
related to the unmanaged code. About 90% of memory utilization is
attributed to ADO.NET code. Right now I am keeping an open connection and
updating the same dataset. After 100,000 records, you can easily imagine
how much crap is sitting in memory. I threw that portion of it together
due to time constraints and need to rewrite it.

Thanks everyone,

Dmitry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top