Al observar cuándo se compilan los métodos JIT utilizando WinDbg/SOS, se muestra que los métodos estáticos no se compilan antes de llamarlos.
Considérese la clase siguiente:
class SomeType
{
[MethodImpl(MethodImplOptions.NoInlining)]
public void InstanceMethod()
{
Console.WriteLine("instance");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void TypeMethod()
{
Console.WriteLine("type");
}
}
uso la opción NoInlining para evitar que el compilador de inlining estos métodos en una versión de lanzamiento.
Si ejecuto una aplicación pequeña como la que se muestra a continuación y adjunto WinDbg, puedo observar cuándo se compilan los métodos JIT.
var st = new SomeType();
Console.WriteLine("attach");
Console.ReadLine();
Console.WriteLine("calling methods");
st.InstanceMethod();
SomeType.TypeMethod();
Console.ReadLine();
En el momento de unir la tabla de métodos para SomeType
se parece a esto:
0:004> !dumpmt -md 0041387c
EEClass: 004114d4
Module: 00412e94
Name: ConsoleApplication2.SomeType
mdToken: 02000007
File: c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Release\ConsoleApplication1.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
6d374960 6d076728 PreJIT System.Object.ToString()
6d368790 6d076730 PreJIT System.Object.Equals(System.Object)
6d368360 6d076750 PreJIT System.Object.GetHashCode()
6d3616f0 6d076764 PreJIT System.Object.Finalize()
0041c035 00413874 NONE ConsoleApplication2.SomeType..ctor()
0041c02d 0041385c NONE ConsoleApplication2.SomeType.InstanceMethod()
0041c031 00413868 NONE ConsoleApplication2.SomeType.TypeMethod()
Después de que los métodos han sido expresamente invocado se ve así:
0:007> !dumpmt -md 0041387c
EEClass: 004114d4
Module: 00412e94
Name: ConsoleApplication2.SomeType
mdToken: 02000007
File: c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Release\ConsoleApplication1.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
6d374960 6d076728 PreJIT System.Object.ToString()
6d368790 6d076730 PreJIT System.Object.Equals(System.Object)
6d368360 6d076750 PreJIT System.Object.GetHashCode()
6d3616f0 6d076764 PreJIT System.Object.Finalize()
0041c035 00413874 NONE ConsoleApplication2.SomeType..ctor()
004700e0 0041385c JIT ConsoleApplication2.SomeType.InstanceMethod()
00470110 00413868 JIT ConsoleApplication2.SomeType.TypeMethod()
es decir, los métodos no se compilan JIT hasta que realmente se invocan.
(Para el registro esto se hizo en .NET 4.5)
Me gustaría pensar que están compilados JIT tan pronto como la primera que se carga el _type_. Esto tiende a ser cuando el ensamblaje se carga. – Oded
¿Su colega tiene una referencia para esto? Quizás también explica el comportamiento. De lo contrario, le estás pidiendo a alguien que explique por qué está sucediendo algo que podría no estar sucediendo. – millimoose