Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
DotNet
acad.assignment.mngr
academic
adonet
aspnet
aspnet.announcements
aspnet.build.controls
aspnet.caching
aspnet.datagridcontrol
aspnet.mobile
aspnet.security
aspnet.webcontrols
aspnet.webservices
clr
compactframework
component_services
datatools
distributed_apps
drawing
faqs
framework
framework.wmi
general
internationalization
interop
languages.csharp
languages.jscript
languages.vb
languages.vb.controls
languages.vb.data
languages.vb.upgrade
languages.vc
languages.vc.libraries
myservices
odbcnet
performance
remoting
scripting
sdk
security
setup
vjsharp
vsa
webservi.enhancements
webservices
windowsforms
windowsforms.controls
winforms.databinding
winforms.designtime
xml
  
 
date: Tue, 1 Jul 2008 04:29:34 -0700 (PDT),    group: microsoft.public.dotnet.framework.interop        back       


Memory leak using pinvoke   
Hi group!
I have a problem with code that seems to leak memory when I use
pinvoke to call into an unmanaged dll. Following is some example code
written to highlight my problem.
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace leakapp {

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    internal class DataContainer {
        public Int32 m_arrayBindIndex = 12;
    }

    class Program {

        static void Main(string[] args) {
            Console.WriteLine("Begin...");
            Console.ReadLine();
            DataContainer ctx = new DataContainer();

                long count = 100000;
                for (long q = 0; q < 5; q++) {
                    for (long i = 0; i < count; i++) {
                        LeakClass(ref ctx);
                    }
                    Console.WriteLine("Outer: " + q.ToString());
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                }

            Console.WriteLine("Done");
            Console.ReadLine();
        }


        /// <summary>
        /// Call the dumy dll with a reference to the DataContainer.
        /// </summary>
        [DllImport("foo.dll", EntryPoint = "LeakClass",
CallingConvention = CallingConvention.Cdecl)]
        public static extern int LeakClass(ref DataContainer cl);

    }
}

On the unmanaged side:
foo.h:
typedef struct _DataContainer {
        int m_arrayBindIndex;
} DataContainer;

extern "C" {
	// Declaration of the leak method
	__declspec(dllexport) void LeakClass(DataContainer **flum);
};

foo.cpp:
#include <objbase.h>
#include "foo.h"

void LeakClass(DataContainer ** flum) {
  // Do nothing!
}

Running the above code will leak 4 bytes on the default process heap
for each all to LeakClass. The leak is identified using DebugDiag.
DebugDiag reports that allocating function is CoTaskMemAlloc which is
called from mscorwks!BlittablePtrMarshalerBase::ConvertSpaceCLRToNative
+23. This seems to be the interop marshaler. The program above is of
course just constructed to highlight my point, but the exact same
"leak-signature" is reported from our production code. This leak
causes the default process heap to be fragmented and eventually the
app will stop. I have tried a several different approaches to identify
why the code above leaks, but I can't figure it out. Changing the
DataContainer from a class to a struct on the managed side removes the
leak, but that is not really the point. I would like to know what why
the code above leaks (I know the leak is not managed but I included
the GC.Collect()-sequence to stop all replys starting with "The GC
won't have time run, of course it seems like a leak..." etc.).
I hope I'm very stupid and have forgotten something obvoius, please
enlighten me.
/Erik
date: Tue, 1 Jul 2008 04:29:34 -0700 (PDT)   author:   eseaflower

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us