Alrighty, another topic about performance monitoring, this time about viewing JIT information. The previous performance monitoring topic was on garbage collection.
When you compile your application with Visual Studio or the command line, you are compiling your C# or VB.Net code into Microsoft Intermediate Language, aka MSIL. The reason for this is so that the IL code can be compiled to native code by the Just In Time (JIT) compiler on the fly, based on the machine the code is executing on. This allows the JIT to create native code that is optimal for the machine the code is running on. Take Omea Reader for example. The MSIL code is identical on my machine and your machine, but when the application is executed, the JIT may produce different native code for your machine than it does for my machine. The JIT is a very in-depth topic, and I’m not going to get into it very much here, but there are plenty of resources out there if you want to know more, such as:
So I’m going to open up my performance monitor and add a few counters that can be found under the Performance Object heading of .Net CLR Jit. I open up my Omea Reader so that it shows up in the box on the right so I can select the Omea Reader instance as the application I want to gather information from. _Global_ is usually never a good choice, as it captures information about every CLR hosted application running on your machine. I select the following counters:
# of Methods Jitted – This counter displays the total number of methods compiled Just-In-Time (JIT) by the CLR JIT compiler since the start of the application. This counter does not include the pre-jitted methods.
% Time in Jit – This counter displays the percentage of elapsed time spent in JIT compilation since the last JIT compilation phase. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase is the phase when a method and its dependencies are being compiled.
Standard Jit Failures – This counter displays the peak number of methods the JIT compiler has failed to JIT since the start of the application. This failure can occur if the IL cannot be verified or if there was an internal error in the JIT compiler.
Total # of IL Bytes Jitted – This counter displays the total IL bytes jitted since the start of the application. This counter is exactly equivalent to the "# of IL Bytes Jitted" counter.
Now I have everything selected that I want. I click OK and stop the performance monitor and close Omea Reader. Now I start the performance monitor and open Omea Reader because I want to know what all is going on and startup, which is where the vast majority of jitting takes place, although, by design, not all of it as we will see below.
Here is what the report and graph look like after Omea Reader has finished loading up.
Report showing JIT information at startup
Graph showing JIT information at startup
As you can see, over 2400 methods were JITted at startup, as inidicated by the blue line. This isn’t all too common due to the number of methods that run in order to startup an application, which is also evident by the yellow line that indicates the percentage of time we have spent in the JIT. You’ll probaby wonder “Why does the max say 147%?” This is because of how the calculations are done, which is percentage of elapsed time spent in JIT compilation since the last JIT compilation phase.
So now that everything is loaded up, Omea Reader is just sitting there doing nothing. Now lets click on the update feeds and see what happens.
Graph showing JIT information during initial update of feeds
You can see from this graph that 413 methods had to be jitted in order for the update my feeds process to occur. That’s one of the great things about the JIT. It didn’t just go in and compile everything possible in the application in anticipation that we might use it. It waited until we actually needed it before it went ahead and did the compilations. You may think this is not so good of a thing, but it greatly increases initial load time for an application running on the .Net framework. It only compiles what it knows it has to use, not what it thinks it is going to use.
You can’t tell, but I’ve actually waited 10 minutes and now am going to click the update feed button again. Since I have over 200 subscriptions, something out there is likely to have been updated, even though it is 10:30 PM for me. Let’s click the update feed button again.
Clicking the update feeds button again
Viola! Nothing happened! See how cool that is? All the methods and code that is required for the process of updating my feeds has already been compiled into machine level assembly language, therefore nothing had to be done other than an execution. Now, everytime I update my feeds, its going to happen lickity-split because everything is already in place and ready to go for that happen. Execution of machine level code only is all that will be required from now on.
So, that is a quick and dirty look at how the JIT works and how to view its measurements. Usually when you do something in an application after startup for the first time, you will see the number of methods increase slightly. Do the same task again, the likelyhood of seeing any increments to the # of methods jitted counter is unlikely.