Re: COM objs problems with .net

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



This looks like the result of a mixing of incompatible technologies, MSMQ is
server class while your COM server looks like client side stuff (involving
bitmaps).
It's also weird that you need to PInvoke to get at a COM interface
reference. That said, you need to make sure that your COM reference lives in
the same apartment as the caller (the Interface user).
IMO your COM object is an STA type object and the eventhandler runs in a
threadpool thread which per default is initialized as MTA, that means that
your COM calls need to be marshaled. This is not a problem as the CLR and
COM takes care of this, but there is a small problem when running this on
the CLR, the STA thread needs to pump messages or the finalizer thread (an
MTA) will block when calling the RCW's Finalize method. A blocked finalizer
is realy a bad thing, no finalizable objects can ever get collected by the
GC and memory consumption will increase until an OOM exception is raised and
your application dies.
So, what I suggest is that you check the COM apartment requirements and the
apartment state of the eventhandler (onMessageReceive). When they are
incompatible you need to create your object in an auxiliary thread
initialized as STA and make sure it pumps messages (you can do this by
calling WatForPendingFinalizers() or WaitOne() ).


Willy.



"zq" <zvkeber@xxxxxxxxx> wrote in message
news:unUQE2$$FHA.2320@xxxxxxxxxxxxxxxxxxxxxxx
> Hi!
>
> Thank you so much for your quick response.
>
> things are as follows. somewhere, inside the code...
>
> [DllImport("...\\Program Files\\ABBYY FineReader Engine
> 7.0\\Bin\\FREngine.dll", CharSet=CharSet.Unicode), PreserveSig]
> private static extern uint GetEngineObject(String devSN, String reserved1,
> String reserved2, ref FREngine.IEngine engine);
>
> and then, later in the evening... :-)
> using FREngine; // of course, i had to tlbimport the frengine first, and
> get my Interop.frengine.dll which I use here
> ...
> // this is an event that runs when a MSMQ message is received
> private void onMessageReceive(object sender, ReceiveCompletedEventArgs
> e)
> {
> private IEngine eng; //
> comes with the FREngine
>
> eng = GetEngineObject("unimportant_string", null, null, ref eng);
>
> eng.AnalyzePage("some_bitmap.jpg"); // and that's all
>
> // do {} while(System.Marshal.ReleaseComObject() != 0);
> eng = null; // I don't need it anymore
> // GC.Collect();
> // GC.WaitForPendingFinalizers();
> }
>
> this is supposed to work normally, right?
> every time it encounters eng=null; the com object is ready for disposal,
> right?
>
> anyway, even if i uncomment last four lines, it still clogs
> up my memory (perfmon's Private Bytes) with additional 45 MBs every time
> the event is fired
>
> btw, there are no internal functions inside the dll for cleaning up memory
> occupied by abbyy's object
> or anything even similar.
>
> thanks a lot for your help!
>
> zvonko
>
>
>
> "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote
> in message news:eDAxVm$$FHA.140@xxxxxxxxxxxxxxxxxxxxxxx
>> zq,
>>
>> Well, if you are returning other COM objects as properties from the
>> COM object that you are using, then you have to make sure you release
>> those when you are done with them.
>>
>> If you aren't using any properties which return any other COM object
>> (or methods which return them), then I would say it is a problem with the
>> COM object itself. However, the behavior you describe indicates that you
>> are probably getting more objects from the object you created, and not
>> releasing them correctly.
>>
>> If your use of the COM object is localized, and you have a huge number
>> of references to other COM objects, then I would actually call GC.Collect
>> to force a collection, which will release the COM objects (assuming you
>> have no other references to them). The finalization of the runtime
>> callable wrapper will cause the reference to be released, and the COM
>> object to be released.
>>
>> Surprizingly enough, there are some areas of the framework that do
>> just that (I think it was something in the System.Windows.Forms
>> namespace, I remember being floored when I saw it a while ago).
>>
>> Ideally, you want to try and release your COM objects when they are
>> done. Being unable to handle the lifetime of your objects is indicative
>> of poor design. If you perform the creation and retreival of the COM
>> objects in the scope of a method, then it should not be a problem at all
>> to do this.
>>
>> Hope this helps.
>>
>> --
>> - Nicholas Paldino [.NET/C# MVP]
>> - mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx
>>
>> "zq" <zvkeber@xxxxxxxxx> wrote in message
>> news:uGGmBx7$FHA.532@xxxxxxxxxxxxxxxxxxxxxxx
>>> Hi!
>>>
>>> I am have a COM object which occupies more and more memory everytime
>>> it's used.
>>>
>>> The "VM size" counter (private bytes) of the process that uses the COM
>>> object keeps on growing when instantiating and using the object
>>> frequently. I tried following strategies for using the object:
>>>
>>> 1. instantiate the object when the app starts, use it frequently (inside
>>> an event handler), and destroy it when the app ends.
>>> 2. instantiate the object inside the event handler, and release it every
>>> time the event handler is finished
>>>
>>> I tried using System.Marshal.ReleaseCOMObject() by calling it untill
>>> it's result returns zero, but it has no effect.
>>>
>>> Once the VM size reaches the pagefile size, the process starts throwing
>>> "out of memory" exceptions if it tries to instantiate other objects
>>> (e.g. a Bitmap object).
>>>
>>> I have narrowed-down the problem to the COM object, because if I
>>> comment-out the part where I use the COM object the "VM size" falls from
>>> cca 250MB to 1MB once when it's done working (i guess it means all other
>>> objects are properly disposed and GC-ed).
>>>
>>> My questions are:
>>>
>>> Is there a way to see if there are any dependant COM objects created
>>> during the COM's work?
>>> Is there a way to destroy all dependant COM objects?
>>>
>>> Can anybody help me please!
>>>
>>> zkeber
>>>
>>
>>
>
>


.



Relevant Pages

  • Re: Expressions in C#...
    ... I would implement another Vec1Container that would have the finalizer ... and a pointer to Vec1 and Vector1 would only point to Vec1Container. ... This is not the same as for objects, where only the reference is stored ... The unmanaged resource is unmanaged memory. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Garbage Colletor
    ... If you're talking about a circular reference (Form ... back to Form's event handler), I'm sure you know that the GC will ... -- I did say originally that with a memory leak there is no reference ... to the memory which can be used to recover it. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Doing one last thing to a WeakReference
    ... This applies therefore to objects that reference it and that it references. ... We recently observed that what seemed like an innocent addition of a small finalizemethod to a class of large objects severely impacted memory usage. ... With a finalizer defined, the object's memory can't be reclaimed as quickly, since it has to stay around until the finalizer thread can run. ... Suppose the finalizer tries to allocate memory? ...
    (comp.lang.java.programmer)
  • Re: Doing one last thing to a WeakReference
    ... 'finalize' takes at least two GC cycles to clean up. ... therefore to objects that reference it and that it references. ... With a finalizer defined, the object's memory can't be ...
    (comp.lang.java.programmer)
  • Re: Doing one last thing to a WeakReference
    ... 'finalize' takes at least two GC cycles to clean up. ... therefore to objects that reference it and that it references. ... We recently observed that what seemed like an innocent addition of a small finalizemethod to a class of large objects severely impacted memory usage. ... With a finalizer defined, the object's memory can't be reclaimed as quickly, since it has to stay around until the finalizer thread can run. ...
    (comp.lang.java.programmer)