4

This is a question I had when I read the answer to this StackOverflow question. When exactly are GCHandles created for managed objects being passed into unmanaged code, and when are these handles freed?

An example where a GCHandle is created - alluded to in the link above but also verified with a memory profiling tool on my end - is within one of the methods called by the following overload of the System.Threading.Timer constructor:

public Timer(TimerCallback callback, object state, int dueTime, int period)

One of the pathway for method calls is the following, read from top to bottom:

System.Threading.Timers.TimerSetup
System.Threading.TimerBase.AddTimer
System.Threading.TimerBase.AddTimerNative

I can see from my memory profiler that the System.Threading.TimerBase.AddTimer method creates GCHandles, but I see no explicit call to GCHandle.Alloc in this method. Where is the GCHandle being created? Is it just an automatic thing that happens in .NET when a method leading to unmanaged code (in this case System.Threading.TimerBase.AddTimerNative) is called?

MiniWalrus
  • 51
  • 4
  • 1
    P/Invoke marshalling shouldn't automatically allocate any GCHandles, since it cannot determine when to release them. Not sure about the method call trace you got there, since I do not find these classes in mscorlib. The one method that seems to interact with native code is `TimerQueue.ChangeAppDomainTimer`, which might do something regarding GCHandles internally. – IS4 Jul 06 '18 at 11:09
  • To provide a bit more information, I am using the JetBrains dotPeek .NET decompiler to look at the implementation details of mscorlib (x86 and .NET Framework v3.5) from the GAC. – MiniWalrus Jul 06 '18 at 16:56

0 Answers0