JIT compilation in action.

From: R. Clayton <rclayton_at_monmouth.edu>
Date: Sat, 31 Jan 2009 12:10:21 -0500
You can watch the jvm jit compile your code with the PrintCompilation option.
For example, here 

  $ cat fact.java
  import java.math.BigInteger;

  public class fact {

    private static final BigInteger one = BigInteger.ONE;

    private static BigInteger
    fact(BigInteger i) {

      BigInteger f = one;

      while (i.compareTo(one) > 0) {
	f = f.multiply(i);
	i = i.subtract(one);
	}

      return f;
      }


    public static void 
    main(String args[]) {

      final BigInteger n = new BigInteger(args.length == 1 ? args[0] : "10");

      for (BigInteger i = one; i.compareTo(n) < 1; i = i.add(one)) {
	System.err.println(i + "! = " + fact(i));
	}
      }
    }

  $

is a simple factorial program.  When you compile and run it as usual you get

  $ javac -Xlint fact.java

  $ java fact
  1! = 1
  2! = 2
  3! = 6
  4! = 24
  5! = 120
  6! = 720
  7! = 5040
  8! = 40320
  9! = 362880
  10! = 3628800

  $

When you run it with PrintCompilation you get

  $ java -XX:+PrintCompilation fact
    1       java.lang.String::hashCode (60 bytes)
    2       java.lang.String::lastIndexOf (156 bytes)
    3       java.lang.String::indexOf (151 bytes)
    4  !    sun.nio.cs.SingleByteDecoder::decodeArrayLoop (308 bytes)
    5       java.io.UnixFileSystem::normalize (75 bytes)
    6  !    sun.nio.cs.SingleByteEncoder::encodeArrayLoop (475 bytes)
  1! = 1
  2! = 2
  3! = 6
  4! = 24
  5! = 120
  6! = 720
  7! = 5040
  8! = 40320
  9! = 362880
  10! = 3628800
    7       java.lang.String::indexOf (166 bytes)
    8       sun.net.www.ParseUtil::encodePath (336 bytes)

  $ 

There are a few options that let you play around with the jit parameters. The
jvm runs as a client by default; the server option runs it as a server, which
changes the jit parameters appropriately:

  $ java -server -XX:+PrintCompilation fact
    1       java.lang.String::hashCode (60 bytes)
    2       java.lang.String::lastIndexOf (156 bytes)
    3       java.lang.String::indexOf (151 bytes)
    4  !    sun.nio.cs.SingleByteDecoder::decodeArrayLoop (308 bytes)
    5       java.io.UnixFileSystem::normalize (75 bytes)
    6  !    sun.nio.cs.SingleByteEncoder::encodeArrayLoop (475 bytes)
  1! = 1
  2! = 2
  3! = 6
  4! = 24
  5! = 120
  6! = 720
  7! = 5040
  8! = 40320
  9! = 362880
  10! = 3628800

  $ 

Because servers run longer than clients, the jvm as a server collects more
run-time statistics so it can make better decisions; in this case some methods
aren't called often enough to reach a decision.  You can also explicitly set
the amount of statistics collected using the CompileThreshold option:

  $ java -XX:CompileThreshold=100 -XX:+PrintCompilation fact
    1       java.lang.String::equals (88 bytes)
    2       java.lang.String::hashCode (60 bytes)
  ---   n   java.io.UnixFileSystem::getBooleanAttributes0
  ---   n   java.lang.System::arraycopy (static)
    3       java.lang.String::lastIndexOf (156 bytes)
    4       java.lang.System::getSecurityManager (4 bytes)
    5       java.lang.String::indexOf (151 bytes)
  1! = 1  
    6       java.lang.String::indexOf (7 bytes)
  2! = 2
  3! = 6
  4! = 24
    7  !    sun.nio.cs.SingleByteDecoder::decodeArrayLoop (308 bytes)
  5! = 120
  6! = 720
  7! = 5040
  8! = 40320
  9! = 362880
  10! = 3628800
    8       java.util.HashMap::getEntry (79 bytes)

  $ java -XX:CompileThreshold=1000000 -XX:+PrintCompilation fact
  1! = 1
  2! = 2
  3! = 6
  4! = 24
  5! = 120
  6! = 720
  7! = 5040
  8! = 40320
  9! = 362880
  10! = 3628800

  $ 

The CompileThreshold parameter unit is calls.  The XX options are unsupported
experimental options; they may not be available on all jvms.  Here's

  http://blogs.sun.com/watt/resource/jvm-options-list.html

a list of jvm options.
Received on Sat Jan 31 2009 - 12:10:40 EST

This archive was generated by hypermail 2.2.0 : Mon Feb 02 2009 - 16:36:24 EST