2

Does .NET and any of its runtimes (CLR, DLR) support off-heap storage as Java does?

p.campbell
  • 98,673
  • 67
  • 256
  • 322
CodingHero
  • 2,865
  • 6
  • 29
  • 42
  • 3
    If I'm not mistaken, this looks like a way to effectively allocate an array of objects in a contiguous memory block (where the array elements are objects themselves, not references). In C#, an array of structs will have exactly this representation, and is a safe construct -- is there a reason you cannot use structs? – cdhowie Jul 26 '13 at 22:02

2 Answers2

7

Yes, you have two similar choices here.

The easiest is just to make an array of structs. When an array of a struct type is allocated, each element is the actual struct value, so the data will be laid out contiguously without any dereferences needed beyond that required to get to a specific array index. This technique gives you type safety, and does not require any special permissions. The array itself will be garbage-collected.

Alternatively, you can follow the spirit of the Java example by using the members of the Marshal class:

  • AllocHGlobal() will allocate a region of memory.
  • FreeHGlobal() will free a previous allocation.
  • The Read*()/Write*() methods can be used to fetch and store numbers. (Similar to the get*()/put*() methods used in the Java sample.)
  • The Copy() overloads can be used to copy a sequence of array elements into or out of this memory.

I would suggest using the array-of-structs approach unless you have a compelling reason to do otherwise. (The "unsafe" approach is required in Java, because Java does not support user-defined value types. C# does.)

If you do need to use the Marshal approach, make sure that you encapsulate these operations in a class that implements the Dispose pattern. This way the consumer can explicitly control the lifetime of the memory allocation, while still allowing the garbage collector to free the memory allocation if the consumer doesn't explicitly dispose of it.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 1
    Rather than create something implementing `IDisposable`, he should create a class derived from `SafeHandle` for this. I looked at several possible implementations publicly available online, and while none of them were exactly what I would want this implementation of [`SafeGlobalMemoryBufferHandle`](http://storagehd.googlecode.com/svn/trunk/StorageHD.FS/SafeGlobalMemoryBufferHandle.cs) is probably the closest and the one I would start with. I would also consider deriving the class from `System.Runtime.InteropServices.SafeBuffer` instead of `SafeHandleZeroOrMinusOneIsInvalid`. – Sam Harwell Jul 27 '13 at 01:05
  • Array of structs will not be out of heap. It will be in heap and there will be GC implications with LOH (if it's large). – Alex des Pelagos Jan 21 '15 at 00:03
-1

This is a decent explanation on unsafe code. C# Unsafe Code I think this is what you were looking for, especially "stackalloc".

This allows you to allocate objects on the stack. However, be careful the pointers in C# are different than in C,C++.

Taka
  • 105
  • 5
  • I initially thought of stackalloc, but this will use the managed execution stack, which is not appropriate for long-lived objects, especially large ones. The frame allocating the object will have to remain alive (you can't "allocate and return" a stackalloc array) and if the array is large, you will very quickly exhaust the available stack space. – cdhowie Jul 26 '13 at 22:06
  • True, but you shouldn't be allocating large arrays on the stack anyways. But upon further research the managed execution stack could cause problems. Here is another [discussion on it](http://stackoverflow.com/questions/8472655/c-sharp-net-stackalloc). – Taka Jul 26 '13 at 22:18
  • That's... basically exactly what I said. :) – cdhowie Jul 26 '13 at 22:30