CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Jan 2008
    Location
    Istanbul - Turkey
    Posts
    3

    Grr, garbage collector, stay away from my arrays!

    Hi;

    I need a memory block allocated on heap (on a fixed posisiton) that GC can't move. I need this because unmanaged code will read data from this memory block on a multi-threaded manner (so "fixed" statement will not work since threads in unmanaged code may still be manipulating this memory though code flow fell out of fixed scope).

    Is this possible with C#? Or do you recommend using nasty GlobalAlloc api to allocate memory on heap manually from C#?

    Thanks all...
    Last edited by BlueEyedCat; January 25th, 2008 at 12:22 PM.
    .NET 2.0 - VStudio2005

  2. #2
    Join Date
    May 2007
    Posts
    811

    Re: Grr, garbage collector, don't move my arrays!

    Look it up pin_ptr, MSDN has info.

  3. #3
    Join Date
    Jan 2008
    Location
    Istanbul - Turkey
    Posts
    3

    Re: Grr, garbage collector, don't move my arrays!

    Thanks for reply but AFAIK, pin_ptr is specific for managed C++ (or am i wrong?). I need a solution for C#. Thanks anyway...
    .NET 2.0 - VStudio2005

  4. #4
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Grr, garbage collector, stay away from my arrays!

    Code:
    GCHandle objHandle = GCHandle.Alloc(array);
    
    // do whatever
    
    objHandle.Free();
    if you have an array of value types you can also pin the array:

    Code:
    GCHandle objHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
    if they're reference types you cant pin it, but that will keep GC from messing w/ it.

  5. #5
    Join Date
    May 2007
    Posts
    811

    Re: Grr, garbage collector, don't move my arrays!

    What about:
    Code:
    IntPtr addressOfMyBuffer = Marshal.AllocHGlobal(yourArrayHere);

  6. #6
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Grr, garbage collector, don't move my arrays!

    Oh if only people would read the documentation....

    fixed statement
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  7. #7
    Join Date
    Oct 2006
    Location
    Timisoara, Romania
    Posts
    123

    Re: Grr, garbage collector, don't move my arrays!

    .NET does has a way of handling this. Use InteropServices and create a GCHandle for your buffer (array).
    Code:
    using System.Runtime.InteropServices;
    
    ...
    
    GCHandle pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    The Pinned GCHandleType tells the garbage collector to pin the array into place so, even when compacting memory, it won't move it. To obtain an IntPtr for that address use
    Code:
    IntPtr ptrToPinned = pinnedBuffer.AddrOfPinnedObject();
    Now you can pass the ptrToPinned to any unmanaged method. When you are done with it, you can let the garbage collecter now by calling
    Code:
    pinnedBuffer.Free();
    I suggest you place the code in a try - finally block to make sure the memory is freed even if an exception occurs.

  8. #8
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Grr, garbage collector, don't move my arrays!

    you cannot pin or obtain the pointer to or get the size of reference types.

    GCHandle is what you need. you can pin it if its members are value types, otherwise you cant, but allocating the handle will keep you from having it moved around.

  9. #9
    Join Date
    May 2007
    Posts
    1,546

    Re: Grr, garbage collector, don't move my arrays!

    Quote Originally Posted by TheCPUWizard
    Oh if only people would read the documentation....

    fixed statement
    It won't work. He explicitly said he needs the object to remain pinned longer than the call into unmanaged land lasts. The array will be filled asynchronously.

    The GCHandle class should do it alright.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  10. #10
    Join Date
    Sep 2004
    Posts
    1,361

    Re: Grr, garbage collector, don't move my arrays!

    Out of curiosity, what kind of C# application needs a block of memory in a fixed location? Even when considering IPC, you share memory blocks via system objects, not actual memory addresses.

  11. #11
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Grr, garbage collector, don't move my arrays!

    You can still use the fixed statement (I do it all the time). you simply implement your architecture so that everything occurs as external method to the fixed statement.

    GCHandle() will work, but can be difficult to properly handle under all exception conditions.

    Also it is generally a really bad idea to pin memory for more than a very short time. Because of the way that the GC works internally, an existing pin effectively prevents GC of that generation entirely!
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  12. #12
    Join Date
    Oct 2006
    Location
    Timisoara, Romania
    Posts
    123

    Re: Grr, garbage collector, don't move my arrays!

    Quote Originally Posted by DeepT
    Out of curiosity, what kind of C# application needs a block of memory in a fixed location? Even when considering IPC, you share memory blocks via system objects, not actual memory addresses.
    A C# application that needs to call a native Windows function. If that function needs a buffer to read from, if you don't pin the memory, the garbage collector might move it and the native function trying to read it will fail.

    A fixed statment works but I, personally, prefer not using unsafe code. Using a GCHandle is the managed way of doing it

  13. #13
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Grr, garbage collector, don't move my arrays!

    Quote Originally Posted by riscutiavlad
    A C# application that needs to call a native Windows function. If that function needs a buffer to read from, if you don't pin the memory, the garbage collector might move it and the native function trying to read it will fail.

    A fixed statment works but I, personally, prefer not using unsafe code. Using a GCHandle is the managed way of doing it
    I dont see how you equate the fixed statement with unsafe code..

    If you look at the fixed statement generated code, it actually creates a GCHandle and releases it inside a finally block so it is perfectly exception safe.

    It is very similar to the lock statement in that it respect...
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  14. #14
    Join Date
    Oct 2006
    Location
    Timisoara, Romania
    Posts
    123

    Re: Grr, garbage collector, don't move my arrays!

    Well, for starters, because using the fixed statement requires an unsafe context.

  15. #15
    Join Date
    May 2007
    Posts
    1,546

    Re: Grr, garbage collector, don't move my arrays!

    Quote Originally Posted by TheCPUWizard
    Also it is generally a really bad idea to pin memory for more than a very short time. Because of the way that the GC works internally, an existing pin effectively prevents GC of that generation entirely!
    Really? Is that documented everywhere? It seems like a fairly serious limitation to have in a garbage collected language, especially one which prides itself on interop with unmanaged code.

    If what you say is true, then all it would take to stop objects being collected would be a single pinned object in each generation. That's something which is pretty simple to do.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured