Re: Memory leak using pInvoke

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • not_a_commie

    Re: Memory leak using pInvoke

    The CLR won't garbage collect until it needs to. You should see the
    memory usage climb for some time before stabilizing. Can you change
    your declaration to use the 'out' keyword rather than a 'ref' keyword?
  • =?Utf-8?B?VmljdG9y?=

    #2
    Re: Memory leak using pInvoke

    Could you tell me why we should use 'out' keyword instead of 'ref' keyword?

    "not_a_comm ie" wrote:
    The CLR won't garbage collect until it needs to. You should see the
    memory usage climb for some time before stabilizing. Can you change
    your declaration to use the 'out' keyword rather than a 'ref' keyword?
    >

    Comment

    • Peter Duniho

      #3
      Re: Memory leak using pInvoke

      On Tue, 24 Jun 2008 01:40:00 -0700, Victor
      <Victor@discuss ions.microsoft. comwrote:
      Could you tell me why we should use 'out' keyword instead of 'ref'
      keyword?
      To the extent that your rising memory footprint is related to the
      allocation of a BITMAPINFOHEADE R object before calling the
      VfwDecoder_GetO utputBitmapInfo Header() function, using an "out" parameter
      instead of "ref" allows you to avoid allocating the object, since it
      wouldn't need to be initialized before passing to the function.

      That said, I'm not really clear on the code example. The DllImport you
      show is for VfwDecoder_Deco mpressNative, not
      VfwDecoder_GetO utputBitmapInfo Header, and you don't show us how you've
      actually declared BITMAPINFOHEADE R in C#. I'm relatively inexperienced
      with p/invoke, so maybe it wouldn't help me understand your question
      better anyway. But it could be useful to someone else with more
      experience with respect to identifying anything about your code that might
      be an issue.

      All that said, the real bottom line here is that as long as you're dealing
      with managed references to objects, the fact that your memory usage climbs
      is not really a problem. The framework manages its use of actual
      allocated memory from the OS independent of your own use of managed
      memory, and it's not uncommon to see the process memory allocations be
      larger than your application's actual use of managed memory.

      Pete

      Comment

      • =?Utf-8?B?ZXNlYWZsb3dlcg==?=

        #4
        Re: Memory leak using pInvoke

        Unfortunatley I don't have a solution to the OPs problem, but I have a
        similar problem and have done some troubleshooting on it. I'm in way over my
        head here so please don't flame me if I state the obvious.
        I have written a very small test program.
        C#:
        using System;
        using System.Collecti ons.Generic;
        using System.Linq;
        using System.Text;
        using System.Runtime. InteropServices ;

        namespace leakapp {
        [StructLayout(La youtKind.Sequen tial, CharSet = CharSet.Unicode )]
        internal class DataContainer {
        public Int32 m_arrayBindInde x = 12;
        }

        class Program {

        static void Main(string[] args) {
        Console.WriteLi ne("Begin...") ;
        Console.ReadLin e();
        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.WriteLi ne("Outer: " + q.ToString());
        GC.Collect();
        GC.WaitForPendi ngFinalizers();
        GC.Collect();
        }

        Console.WriteLi ne("Done");
        Console.ReadLin e();
        }


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

        }
        }

        foo.h:
        typedef struct _DataContainer {
        int m_arrayBindInde x;
        } DataContainer;

        extern "C" {
        // Declaration of the compression method
        __declspec(dlle xport) void LeakClass(DataC ontainer **flum);
        };

        foo.cpp:
        // This is the main DLL file.
        #include <objbase.h>
        #include "foo.h"

        void LeakClass(DataC ontainer ** flum) {
        }


        (Don't comment on the usefullness of the code, it is only an example, as is
        probably obvious from the naming etc. :-))

        Running the program and attaching DebugDiag will reveal that on every call
        to the unmanaged method there is a leak of 4 bytes. The leak will be on the
        default process heap due to a call to CoTaskMemAlloc (used by the
        interop-marshaler). DebugDiag reports that the allocations come from
        mscorwks!Blitta blePtrMarshaler Base::ConvertSp aceCLRToNative+ 23 . I can even
        remove the only field in the class DataContainer passed to the unmanaged
        method, this will result in a leak of 1 byte per call. The leak is not in
        managed memory, but just to avoid all replys about "The GC hasn't run yet.."
        etc. I included the GC.Collect()-sequence.
        The above problem arises in our production servers. These small memory leaks
        will fragment the default process heap (CoTaskMemAlloc heap) eventualy
        crashing the app.
        So, am I doing something stupid here? I have read about pinvoke and interop
        marshaling but I can't find anything that is wrong with the code. Changing
        the managed definition to a struct solves the problem. I would still like to
        know what is wrong with the code I posted above.
        Hope someone has some insight into thi.
        /Erik


        "Peter Duniho" wrote:
        On Tue, 24 Jun 2008 01:40:00 -0700, Victor
        <Victor@discuss ions.microsoft. comwrote:
        >
        Could you tell me why we should use 'out' keyword instead of 'ref'
        keyword?
        >
        To the extent that your rising memory footprint is related to the
        allocation of a BITMAPINFOHEADE R object before calling the
        VfwDecoder_GetO utputBitmapInfo Header() function, using an "out" parameter
        instead of "ref" allows you to avoid allocating the object, since it
        wouldn't need to be initialized before passing to the function.
        >
        That said, I'm not really clear on the code example. The DllImport you
        show is for VfwDecoder_Deco mpressNative, not
        VfwDecoder_GetO utputBitmapInfo Header, and you don't show us how you've
        actually declared BITMAPINFOHEADE R in C#. I'm relatively inexperienced
        with p/invoke, so maybe it wouldn't help me understand your question
        better anyway. But it could be useful to someone else with more
        experience with respect to identifying anything about your code that might
        be an issue.
        >
        All that said, the real bottom line here is that as long as you're dealing
        with managed references to objects, the fact that your memory usage climbs
        is not really a problem. The framework manages its use of actual
        allocated memory from the OS independent of your own use of managed
        memory, and it's not uncommon to see the process memory allocations be
        larger than your application's actual use of managed memory.
        >
        Pete
        >

        Comment

        Working...