What are pinned objects?

C#MemoryGarbage Collection

C# Problem Overview


I am trying to find a memory leak using ants memory profiler, and I've encountered in a new term:

Pinned objects.

Can some one give me a good & simple explanation about what this objects are, How can I pinn/Unpinn objects, and detect who pinned objects?

Thanks

C# Solutions


Solution 1 - C#

A pinned object is one that is not allowed to move. The garbage collector is normally compacting the memory in that it moves all objects to "one or more clusters". This is to create large chunks of free space.

This basically means if someone else (outside) has a pointer to the memory address of an object, this may point to random content - as the object has moved.

Pinning an object tells the GC to NOT MOVE IT. This is normally useless and ONLY makes sense when working with pointers - like when using PInvoke. Sometimes you need to turn in an address to a structure (in the memory layout term), and if that is implemented in a class, you have to pin that.

To answer concrete:

  • You can not find out who pinned an obiect.
  • Pinning is done with the FIXED statement. This is only allowed in unsafe code.

Check:

http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

Solution 2 - C#

A pinned object is one that cannot be moved around by the garbage collector, meaning its address has to be kept the same because someone else, usually some piece of non managed code, depends upon the object being at a definite memory address.

Usually the garbage collector has freedom to relocate objects in memory. In managed code, as the garbage collector has the ability to access all references, it can freely remap an object to a different location and then update all references to that object so that the process is transparent to the running code. That way, the GC has the ability to better organize the program's memory and compact it if needed.

When an non-managed object is interacting with your code (in unsafe sections,) a situation may arise where there's a pointer somewhere to a piece of your code — for example, to a piece of memory addressed in your code that is being handled by an external COM call. This memory can't be remapped because the COM call is expecting the object to be in a given address and thus, if it was moved, the GC wouldn't have any way to notify the COM object of that change, resulting in an access violation or worse.

Solution 3 - C#

The reason you might pin an object is if you are making calls to unmanaged code.

When the garbage collector runs it may remove an object that's no longer required. This leaves a "hole" of free space in the heap. The GC then compacts the heap by moving the remaining objects together to make sure the free space is in one continous block (a bit like defragmenting your hard disk).

It also updates all the references (in the managed code) to any objects that have been moved as part of the compaction.

If you are working with unmanaged code (e.g. some external C++) and give it a pointer to an object, there is no way for the GC to tell the unmanaged code that the object has moved after it has run. Therefore you might mark the object your sharing with the external code as pinned so that you don't have the problem of the pointer becoming invalid.

Solution 4 - C#

In order to pin objects you can use the fixed keyword:

> The fixed statement prevents the > garbage collector from relocating a > movable variable. The fixed statement > is only permitted in an unsafe > context.

An example I've seen before is breaking up a long value into bytes so that it can be encoded into a serial key. This was done in an unsafe context in order to get the pointer. Intermittent errors started occurring because garbage collection would happen halfway through the process of getting the individual bytes. The value would get relocated and we were left with half correct bytes, half garbage bytes.

The solution for us was to use the BitConverter class. If you look at the underlying code of the BitConverter class, you will see it uses the fixed keyword to pin the byte array while obtaining the bytes from the variable.

Solution 5 - C#

Pinned objects are used when communicating with non-managed code. In managed code the garbage collector is free to move memory blocks around, as it knows about all references to the memory block and can update those accordingly.

When communicating with non-managed code (e.g. Win-API) pointers to data or buffers are often passed as argument. If the garbage collector was free to move that data, the pointers would suddenly become invalid. As the pointer is transferred to unmanaged code, it is not possible for the GC to update the pointer - or even know of where it is used. To prevent memory moving and make sure that the data stays in the place known by the unmanaged code's pointer the object can be pinned.

Solution 6 - C#

A pinned object is one that has a set location in memory.

Normally the garbage collector will compact the managed heap, which changes the location of the objects in memory. If you have some unmanaged code that refers to some C# object you have created you may want to be able to reference the memory location absolutely. Pinning the object enables you to do this with certainty.

You can create them using the fixed statement: http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

Solution 7 - C#

got it from msdn "A pinned object is one that the garbage collector cannot move in memory"

http://msdn.microsoft.com/en-us/library/x2tyfybc(VS.71).aspx

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsagieView Question on Stackoverflow
Solution 1 - C#TomTomView Answer on Stackoverflow
Solution 2 - C#Jorge CórdobaView Answer on Stackoverflow
Solution 3 - C#PaoloView Answer on Stackoverflow
Solution 4 - C#Richard NienaberView Answer on Stackoverflow
Solution 5 - C#Anders AbelView Answer on Stackoverflow
Solution 6 - C#JonCView Answer on Stackoverflow
Solution 7 - C#CliffCView Answer on Stackoverflow