0

.net memory profiler report, which shows smtpclient instances not GCedThis is the VC++ code, which is using C# COM DLL to send messages. This code is executed multiple times as I want to send multiple emails. With every call I see memory increase in Task Manager and it never goes down again...

void CTestMailLibraryDlg::OnOK() 
{
CoInitialize(NULL);

HRESULT hr;
IMailLibraryPtr  pLib;
hr = pLib.CreateInstance(CLSID_MailSetup);

if(pLib != NULL)
{
    BSTR server = SysAllocString(L"smtp.gmail.com"); 
    pLib->MailServerSetup(server);
    SysFreeString(server);

    BSTR To = SysAllocString(L"rahulppawar22@gmail.com"); 
    pLib->AddToRecipient(To);
    SysFreeString(To);

    BSTR from = SysAllocString(L"apogeeinsight1@gmail.com"); 
    BSTR subject = SysAllocString(L"subject"); 
    BSTR msg = SysAllocString(L"msg"); 
    BSTR username = SysAllocString(L"apogeeinsight1@gmail.com"); 
    BSTR password = SysAllocString(L"Apogee$1234"); 
    BSTR attachment = SysAllocString(L""); 

    pLib->SendMail(from,subject,msg,attachment,587,username,password,1);

    SysFreeString(from);
    SysFreeString(subject);
    SysFreeString(msg);
    SysFreeString(username);
    SysFreeString(password);
    SysFreeString(attachment);
}

CoUninitialize();
}

This is C# COM DLL code. Following send function is called multiple times during each call memory is getting piled up and never again released..

namespace MailLibrary
{
[ComVisible(true), GuidAttribute("FA1DD41F-1547-4A38-BE20-1BFE28EAF87C")]
public class MailSetup : IDisposable, IMailLibrary
{
    MailMessage _mail;
    SmtpClient _smtpobj;
    public void MailServerSetup(string serverName)
    {
        _mail = new MailMessage();
        _smtpobj = new SmtpClient(serverName);
    }

    public void AddToRecipient(string toAddress)
    {
        _mail.To.Add(toAddress);
    }

    public void AddCcRecipient(string ccAddress)
    {
        _mail.CC.Add(ccAddress);
    }

    public void AddBccRecipient(string bccAddress)
    {
        _mail.Bcc.Add(bccAddress);
    }

    public string SendMail(string fromAddress,string subject, string body, string strAttachment, int port,string username, string password, bool bSsl)
    {
        string strReturn = "";
        try
        {
            _mail.From = new MailAddress(fromAddress);
            _mail.Subject = subject;
            _mail.Body = body;
            if (strAttachment != "")
            {
                Attachment attachment = new Attachment(strAttachment);
                _mail.Attachments.Add(attachment);
            }
            _smtpobj.Port = port;
            _smtpobj.Credentials = new System.Net.NetworkCredential(username, password);
            _smtpobj.EnableSsl = bSsl;
            _smtpobj.Send(_mail);
            Cleanup(); 

        }
        catch (Exception ex)
        {
            Cleanup();
            strReturn = ex.ToString();
        }
        return strReturn;
    }

    public void Cleanup()
    {
        _smtpobj.ServicePoint.CloseConnectionGroup(_smtpobj.ServicePoint.ConnectionName);
        _mail.Dispose();
        _smtpobj.Dispose();
       Debug.Write("RP:Cleanup Done");
    }

    public virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            Dispose();
        }
    }
    public void Dispose()
    {
        this.Dispose(true);
        Cleanup();
        GC.SuppressFinalize(this);
    }
}

}

User420
  • 50
  • 7
  • Possible duplicate of [Using statement vs. IDisposable.Dispose()](https://stackoverflow.com/questions/10984336/using-statement-vs-idisposable-dispose) – mjwills Mar 06 '18 at 08:57
  • I have tried using using statement, it did not help . – User420 Mar 06 '18 at 09:02
  • Please show that code then, since your above code is almost certainly incorrect due to your explicit use of `Dispose`. Also please include the **entirety** of the `MailSetup` class. – mjwills Mar 06 '18 at 09:02
  • hi @mjwill I posted entire code here.. pls have a look.Also this is not a duplicate of using statement... it is a different story – User420 Mar 06 '18 at 10:14
  • The AddRef() call is not correct, CreateInstance() already does that for you. – Hans Passant Mar 06 '18 at 11:59
  • @HansPassant - I have Removed AddRef() call. But unfortunately this doesn't change memory usage. – User420 Mar 06 '18 at 13:01
  • Are you calling the [`CoUninitialize` function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms688715(v=vs.85).aspx) for each call to the [`CoInitialize` function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx)? – Phil Brubaker Mar 06 '18 at 16:38
  • @PhilBrubaker asks a good question. Really, you should just call AfxOleInit() in your application InitInstance() method before your program does anything with COM. And besides the AddRef() to delete that Hans mentioned, you should remove the Release() which was paired with the AddRef(). Your program might increase with memory until the .Net runtime does a garbage collection. – Joseph Willcoxson Mar 07 '18 at 05:22
  • Hi @JosephWillcoxson , I have done suggested changes. and updated latest code. Still I see no improvements. – User420 Mar 07 '18 at 12:14
  • I probably should have been more clear... Use the AfxOleInit() instead of the CoInitialize()/CoUninitialize() pair... Also, at the end of your Cleanup() method I would set _mail and _smtobj to null, and I would try calling GC.Collect() at the end of it...and make sure your Cleanup() method checks to make sure the values of those objects aren't null. – Joseph Willcoxson Mar 07 '18 at 17:52
  • @JosephWillcoxson, done with the changes you suggested, what I now observe is memory fluctuations in Task manager. But still entire memory is not cleaned up and leaves behind some residue. – User420 Mar 08 '18 at 06:57
  • Memory fluctuations are observed possibly because of Gc.Collect() call you suggested. But problem is still unsolved. – User420 Mar 08 '18 at 08:03
  • I have used .net memory profiler to analyse this. I have seen a message where it shows 2000 instances of smtpclient are disposed but not GCed. I have attached snapshot here pls have a look – User420 Mar 20 '18 at 09:03
  • If you see "fluctuations" then the GC is doing its job. Having 2000 objects ready to be collected is not abnormal, smtpclient is not a big object. It is only ever a leak when you can crash your program with OOM. – Hans Passant Mar 20 '18 at 10:00

0 Answers0