Объяснение производительности: код работает медленнее после прогрева

Приведенный ниже код выполняет один и тот же расчет 3 раза (он мало что делает: в основном складываются все числа от 1 до 100 м). Первые 2 блока работают примерно в 10 раз быстрее, чем третий. Я запустил эту тестовую программу более 10 раз, и результаты показывают очень небольшую разницу.

Во всяком случае, я бы ожидал, что третий блок будет работать быстрее (JIT-компиляция), но типичный вывод:

35974537
36368455
296471550

Может кто-нибудь объяснить, что происходит? (Просто чтобы прояснить, я здесь не пытаюсь что-то исправить, просто пытаюсь лучше понять, что происходит)

Замечания:

no GC is run during the program (monitored with -XX:+PrintGC) tested with Oracle JDK versions 1.6.0_30, 1.7.0_02 and 1.7.0_05 also tested with the following parameters: -XX:+PrintGC -Xms1000m -Xmx1000m -XX:NewSize=900m => same result it the block is put in a loop instead, all runs are fast if the block is extracted to a method, all runs are fast (whether the method is called 3 times or in a loop makes no difference)
public static void main(String... args) {
    //three identical blocks
    {
        long start = System.nanoTime();
        CountByOne c = new CountByOne();
        int sum = 0;
        for (int i = 0; i < 100000000; i++) {
            sum += c.getNext();
        }
        if (sum != c.getSum()) throw new IllegalStateException(); //use sum
        long end = System.nanoTime();
        System.out.println((end - start));
    }
    {
        long start = System.nanoTime();
        CountByOne c = new CountByOne();
        int sum = 0;
        for (int i = 0; i < 100000000; i++) {
            sum += c.getNext();
        }
        if (sum != c.getSum()) throw new IllegalStateException(); //use sum
        long end = System.nanoTime();
        System.out.println((end - start));
    }
    {
        long start = System.nanoTime();
        CountByOne c = new CountByOne();
        int sum = 0;
        for (int i = 0; i < 100000000; i++) {
            sum += c.getNext();
        }
        if (sum != c.getSum()) throw new IllegalStateException(); //use sum
        long end = System.nanoTime();
        System.out.println((end - start));
    }
}

public static class CountByOne {

    private int i = 0;
    private int sum = 0;

    public int getSum() {
        return sum;
    }

    public int getNext() {
        i += 1;
        sum += i;
        return i;
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос