locked
Release COM objects in C# (mshtml) RRS feed

  • Question

  • Hello!

    How to release COM objects properly? I'm calling Marshal.FinalReleaseComObject on each object I use, but it seems that memory is not freed. I'm using mshtml to parse content of html pages. So if I'm running the following code in a cycle then apps memory usage is growing.

     

    HTMLDocument oDoc = new HTMLDocument();
          IHTMLDocument2 doc = (IHTMLDocument2)oDoc;
          doc.write (new object [] {contentStr});
          doc.close ();
          oDoc.close();
    <br/>
    ...<br/>
    ...<br/>
           if (doc != null)
          {
            Marshal.FinalReleaseComObject(doc);
          }
          if (oDoc != null)
          {
            Marshal.FinalReleaseComObject(oDoc);
          }
    

    Thursday, August 26, 2010 8:24 AM

Answers

  • a couple years ago someone told me: release everything what you've touched.

    so if you call sub com instanse (new object is created) you should:

     

    A aCom;
    B bCom;
    
    try
    {
     aCom = CreateCom();
     bCom = aCom.B;
     
    if (bCom != null)
    {
     // do something
    }
    }
    finally
    {
    if (bCom != null)
    Marshal.FinalReleaseComObject(bCom);
    
    if (aCom != null)
    Marshal.FinalReleaseComObject(aCom);
    }
    so you should change your code a little bit. first you have to assign parentElementto variable and then check if it's null

     


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 9:33 AM
  • hi,

     

    no. string is a value type. That's because its immutability. so after com object is released string should be alive ;)


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 10:59 AM
  • String is a reference type. Not a value type.

    But they are copied from COM into .Net string objects. So, they don't hold any reference to COM objects.

    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 2:12 PM
  • hi,

     

    please read: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/0c31ef8c-d4e1-4590-8b70-e9534e9e3cd5


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Proposed as answer by DK. Da Thursday, August 26, 2010 8:55 AM
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 8:44 AM

All replies

  • hi,

     

    please read: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/0c31ef8c-d4e1-4590-8b70-e9534e9e3cd5


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Proposed as answer by DK. Da Thursday, August 26, 2010 8:55 AM
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 8:44 AM
  • Thank you for your answer! I've read that topic before thoguh.

    Could you tell me do I have to release memory in the following case:

    if (parElem.parentElement != null && parElem.parentElement.parentElement != null)
    {
      parElem = parElem.parentElement.parentElement;
    }
    

    I mean if I called parentElem property or even more parentElem.parentElem called, then does the memory is allocated for another object or not?

     

    Thanks,

    Victor

    Thursday, August 26, 2010 9:23 AM
  • a couple years ago someone told me: release everything what you've touched.

    so if you call sub com instanse (new object is created) you should:

     

    A aCom;
    B bCom;
    
    try
    {
     aCom = CreateCom();
     bCom = aCom.B;
     
    if (bCom != null)
    {
     // do something
    }
    }
    finally
    {
    if (bCom != null)
    Marshal.FinalReleaseComObject(bCom);
    
    if (aCom != null)
    Marshal.FinalReleaseComObject(aCom);
    }
    so you should change your code a little bit. first you have to assign parentElementto variable and then check if it's null

     


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 9:33 AM
  • Thank you for the clarification! Thinking about it now and have got your answer. So I'll do it as you suggested.

    That checking for not null and releasing COM objects makes code less readable...

    BTW, Is there any better option to parse HTML documents and get its DOM structure instead of using MSHTML COM?

     

    Thanks,

    Victor

     

     

    Thursday, August 26, 2010 9:43 AM
  • hi,

     

    yes it's true, the code is less readable.instead of this you can write your own class (IDisposable) or something like this

     

    about DOM structure. i have no idea. i've never parsed html documents


    BR, Karol. mark as answer/vote as helpful if it helped you
    Thursday, August 26, 2010 9:54 AM
  • One more question:

    IHTMLElement aelem;
    
    // skipped
    
    string title = aelem.innerText;
    
    if (aelem != null)
    {
     Marshal.finalReleaseComObject(aelem);
    }
    
    Does title variable holds a reference to string in aelem COM object???
    Thursday, August 26, 2010 10:28 AM
  • hi,

     

    no. string is a value type. That's because its immutability. so after com object is released string should be alive ;)


    BR, Karol. mark as answer/vote as helpful if it helped you
    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 10:59 AM
  • String is a reference type. Not a value type.

    But they are copied from COM into .Net string objects. So, they don't hold any reference to COM objects.

    • Marked as answer by Mike Dos Zhang Wednesday, September 1, 2010 7:40 AM
    Thursday, August 26, 2010 2:12 PM