Quote from ( Safe in C# not in C++, simple return of pointer / reference, answer 3) by Eric lippert.
Also, note that it is not any reference to the P
There're all kinds of root objects, like CLR internal objects, metadata objects, etc. This post may help:
Variables and GC Roots
- A variable of a Value Type is direct representation of the address of the Value Type instance on stack
- A reference variable to a Value Type instance is called Managed Pointer and is a pointer to the starting address of the Value Type instance on stack
- A variable of a Reference Type (UDT, Array, String, Delegate and Interface type variables) is a pointer to the Reference Type instance created on GC heap
- CPU registers can contain Managed Pointers or Object References
- AppDomain wide Handle tables contain GC handles that are pointers to the pinned Reference Type instances in memory. These Handle tables also contain Managed Pointers (or Object References?) to the static Value Type instances and Object References to the static Reference Type instances
- Thread Local Storage (TLS) can contain Object References
- FReachable Queue contains Object References of the Reference Types that are NOT referenced by any of the above variable types and for which finalize method call is pending
CLR's Garbage Collector uses the above variables, also called GC roots, to track down the Object References during garbage collection phase. Any Reference Type instance located in GC heap, for which there is no Object Reference in any of the above variable types (except for the FReachable Queue), is considered a candidate for garbage collection and is removed from GC heap. If the Reference Type instance being removed implements the Finalize method, then the Object Reference is put on FReachable Queue for calling the Finalize method by a separate Finalizer thread. Once the Finalizer thread completes Finalize method call on an Object Reference, the corresponding Reference Type instance is removed from the GC heap.