|
-
January 25th, 2008, 12:13 PM
#1
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
-
January 25th, 2008, 12:41 PM
#2
Re: Grr, garbage collector, don't move my arrays!
Look it up pin_ptr, MSDN has info.
-
January 25th, 2008, 01:50 PM
#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
-
January 25th, 2008, 02:20 PM
#4
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.
-
January 25th, 2008, 02:22 PM
#5
Re: Grr, garbage collector, don't move my arrays!
What about:
Code:
IntPtr addressOfMyBuffer = Marshal.AllocHGlobal(yourArrayHere);
-
January 25th, 2008, 02:22 PM
#6
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
-
January 25th, 2008, 02:26 PM
#7
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.
-
January 25th, 2008, 02:26 PM
#8
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.
-
January 25th, 2008, 02:35 PM
#9
Re: Grr, garbage collector, don't move my arrays!
 Originally Posted by TheCPUWizard
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.
-
January 25th, 2008, 02:43 PM
#10
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.
-
January 25th, 2008, 02:48 PM
#11
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
-
January 25th, 2008, 03:07 PM
#12
Re: Grr, garbage collector, don't move my arrays!
 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
-
January 25th, 2008, 03:18 PM
#13
Re: Grr, garbage collector, don't move my arrays!
 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
-
January 25th, 2008, 03:24 PM
#14
Re: Grr, garbage collector, don't move my arrays!
Well, for starters, because using the fixed statement requires an unsafe context.
-
January 25th, 2008, 08:12 PM
#15
Re: Grr, garbage collector, don't move my arrays!
 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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|