Performance Monitoring – JIT compilations

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:

David Notario’s WebLog – CLR and JIT Compiler. Specifically, you may want to start with his article The CLR x86 JIT, an overview.

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

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

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.

This entry was posted in .Net Development. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

Leave a Reply