Groups | Blog | Home
all groups > dotnet interop > march 2005 >

dotnet interop : Memory leak?


Steven Kilby
3/26/2005 12:13:55 AM
Hi,

I'm not sure, but I may have found a memory leak between vb6 and .net. Of
course, it is possible that I just don't understand something correctly or I
did something wrong. In any event, what I've done is create a C# class
library that exposes an interface through COM. If I instantiate this
interface in vb6 it is never released. I included a finalize method and it
is never called. If I instantiate the same interface in C++ it is released
as expected and the finalize method is called. I understand that the
execution of the finalize method is non-deterministic. I've tried waiting
for extended periods and it is just never called from the vb app. I've
boiled it down to a very simple example. Below is a C# server, a C++
client, and a VB6 client. The finalize method is called everytime when the
C++ app exits and it is never called when the VB6 client exists. If you
compile these the VB6 app is a console app, so you'll have to run 'editbin
/SUBSYSTEM:CONSOLE' on the exe. If any can explain the behavior, I would
appreciate it.

Thanks
Steven

================= C#
using System;

using System.Runtime.InteropServices;

namespace MemLeak

{

/// <summary>

/// Summary description for IMemLeak.

/// </summary>

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

[GuidAttribute("E2F25E23-40D4-4f9b-BC2F-0D6BA932DA31")]

[ComVisible(true)]

[CLSCompliant(false)]

public interface IMemLeak

{

void DummyMethod();

}

/// <summary>

/// Summary description for MemLeakObj.

/// </summary>

[ClassInterface(ClassInterfaceType.None)]

[GuidAttribute("66BAA837-CCA4-4a07-AC6C-8EFBE22928BB")]

[ProgId("MemLeak.MemLeakObj.1")]

[ComVisible(true)]

public class MemLeakObj : IMemLeak

{

public MemLeakObj()

{

Console.WriteLine("MemLeakObj: Constructor");

}

~MemLeakObj()

{

Console.WriteLine("MemLeakObj: Finalizer");

}

#region IMemLeak Members

public void DummyMethod()

{

Console.WriteLine("MemLeakObj: DummyMethod");

}

#endregion

}

}

================== VB6

Option Explicit

Public Const STD_OUTPUT_HANDLE = -11&

Public Declare Function stdout Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_OUTPUT_HANDLE) As Long

Public Declare Function WriteFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToWrite As
Long, _
lpNumberOfBytesWritten As Long, Optional ByVal lpOverlapped As Long = 0&) As
Long
Sub Main()

Dim sWriteBuffer As String
Dim lBytesWritten As Long
Dim hStdOut As Long

sWriteBuffer = "MemLeak VB Client" & vbCrLf
hStdOut = stdout()
WriteFile hStdOut, sWriteBuffer, Len(sWriteBuffer), lBytesWritten

Dim o As Object
Set o = CreateObject("MemLeak.MemLeakObj.1")
Set o = Nothing
End Sub

==================== C++

// This is the main project file for VC++ application project

// generated using an Application Wizard.

#include "stdafx.h"

#include <objbase.h>

#define CRTDBG_MAP_ALLOC

#include <stdlib.h>

#include <crtdbg.h>

#using <mscorlib.dll>

using namespace System;

int _tmain()

{

// TODO: Please replace the sample code below with your own.

Console::WriteLine(S"MemLeak C++ Client");

::CoInitialize(NULL);

CLSID clsid;

HRESULT hr = ::CLSIDFromProgID(L"MemLeak.MemLeakObj.1", &clsid);

IDispatch *p = NULL;

hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch,
(void**)&p);

p->Release();

_CrtDumpMemoryLeaks();

::CoUninitialize();

return 0;

}



Daniel Petersson, Cefalo
3/29/2005 2:43:02 AM
There is no such simple leak! The only reason for not finalizing the
object during execution is that you keep a reference to it. Therefore
you probably miss a Release from VB. (set to Nothing)

To gurarantuee the the object is created you shall always make a
call to it. For example Remoted objects are not created until the first
call is made. (I'm not certain how the runtime behaivs with COM but
I assume that the lazy paradigm is common to avoid overhead)

The _CrtDumpMemoryLeaks will no show any leaks on the managed
heap!

// Daniel

[quoted text, click to view]
AddThis Social Bookmark Button