Re: Garbage collectable pinned arrays!



Willy Denoyette [MVP] wrote:
"Ben Voigt [C++ MVP]" <rbv@xxxxxxxxxxxxx> wrote in message
news:%23bjU84abIHA.5400@xxxxxxxxxxxxxxxxxxxxxxx
This is not what pinned means in this context. The objects on the
LOH (all version of the CLR) are at a fixed address for their life
time, but that doesn't mean they are pinned. Pinning is an explicit
action

Ok, but then they don't require pinning. In any case they
inherently have the fixed address which requires pinning to obtain
for normal objects.

As I said before, pinning is an action performed by the Interop layer
*when the GC initiates a scan, and it's not done by means of a call to
GCHandle.Alloc. You only need to pin "explicitely" when you are
passing an object to unmanaged code and you need to keep the object
alive and at fixed location after the PInvoke call returned, during
the call the PInvoke layer takes care of eventual pinning.

That's not an unusual case. I've already given two examples of APIs in
widespread use which require a buffer to stay in one position after the
initial function call which accepts the pointer.

Also, you keep ignoring my remark that the fact that addresses of
*Large* objects are fixed is a convenience of the current version of
the CLR, nothing stops MS from changing this.

Which is why the OP is asking for a keyword / MSIL flag that will let the
runtime know that the object is intended to be fixed for as long as it
lives. It would be an implementation detail whether the memory is allocated
from the LOH, OLE task allocator, etc, etc. Also I don't think that
sacrificing GC for such objects would necessarily be a big loss, they either
will live to the end of the process anyway, or they can be explicitly freed.

Hence my suggestion of T[] Marshal.AllocCoTaskMem<T>(int elementCount), T
required to be a "reference free" value type, meaning all members are
"reference free" value types.



It would be useful to request that a particular buffer not be
subject to relocation by the GC. Probably the easiest way to do
this would be to place it in the LOH. The OLE task allocator or
HGlobal allocator, both of which are already exposed by the Marshal
class in a typeless way, would be other options. It could be as
simple as adding a T[] Marshal.AllocCoTaskMem<T>(int elementCount)
override.

But now you are allocating from the unmanaged heap (COM heap or CRT
heap or whatever). So now you will incur the costs of copying back
and forth, again this depends on the semantics, but might be a
solution when you need to pass large data chunks to unmanaged land.

Why? .NET could create a proper array descriptor storing the
metadata alongside and access it directly.


Where? outside of the GC heap? Who's going to "manage" these objects
then? As you may know, there are other cheap means to pass fixed
buffers to managed code.

The CLR has no trouble with data outside the GC heap, it just can't hold
references to objects inside the GC heap (because then objects could be
reachable but the GC wouldn't know that). For example, MSIL instructions
have no trouble accessing structures on the stack.


Willy.


.



Relevant Pages

  • Re: Garbage collectable pinned arrays!
    ... Pinning is an explicit action ... but then they don't require pinning. ... Also, you keep ignoring my remark that the fact that addresses of *Large* objects are fixed is a convenience of the current version of the CLR, nothing stops MS from changing this. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Cannot convert parameter from cli::interior_ptr to HRASC
    ... Pinning tells the garbage collector that the object can't be moved in the memory, because there is a native pointer to it. ... Similarly, if you have a large managed object or array that needs to be passed to a native function, just pin it. ... Pinning appears to copy the object to the large object heap, so for large objects it's trivial, and for small objects it incurs the copy that you probably chose pass-by-pointer to avoid. ... From testing with PtrToStringChars with and without pinning, the pointer moved significantly for small strings, and not at all for large strings, and the pinned small string looked like it moved into the area with the large strings. ...
    (microsoft.public.dotnet.languages.vc)
  • Re: unmanaged vs managed.
    ... Is using fixed or is pinning an object the same thing?(Ignoring the fact ... This leads to heap fragmentation. ... Would using unmanaged memory be better in this case? ... Allocate a big array and keep it around. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: unmanaged vs managed.
    ... each of these is probaly a bigger "real" issue than the GC heap ... I would rather use structure pointers to a chunk of fixed memory. ... I have also read that pinning hurts the process of garbage collection, ... Does unmanage memory ever move? ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: unmanaged vs managed.
    ... I couldnt imaging tormenting the managed heap with that kind of through ... I would rather use structure pointers to a chunk of fixed memory. ... If I put all, say, 5000+ records on the heap individualy, then the heap has ... fixedor pinning via GCHandle. ...
    (microsoft.public.dotnet.languages.csharp)

Loading