Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process stalling in simple for-loop, dependent on iterator type (potential JVM bug?)

Tags:

java

for-loop

jvm

A very simple for-loop that I used as a dummy to keep my machine busy blocked all processes of my JVM. The stalling persisted even in the most simple constellation.

Here is an example of two for-loops (the first blocking, the second not), the only difference being the type of the iterator 'i', namely int vs. long:

public class Main {
public static void main(String[] args) {

    Timer timer = new Timer();
    timer.schedule(new MyTimerHandler(), new Date(), 1000);
    float b = 1;

    // after a few seconds this loop uses 200% CPU and blocks the timer 
    for (int i=0; i<2000000000; i++) {
        b += i/3.141592;
    }
    System.out.println("Result: " + b);
    b = 1;

    // this version uses 100% CPU throughout the entire loop and doesn't block the timer
    for (long i=0; i<2000000000L; i++) {
        b += i/3.141592;
    }
    System.out.println("Result: " + b);
    timer.cancel();
 }
}
// helps to show whether the JVM is stalled or not
class MyTimerHandler extends TimerTask {
    @Override
    public void run() {
        System.out.println("timestamp=" + new Date().toString());
    }
}

We have reproduced the problem on two different machines/jvms:

  • Arch Linux 3.7.7-1-ARCH ... x86_64 GNU/Linux java version "1.7.0_09", Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
  • OSX 10.8.2 ... x86_64 java version "1.7.0_07", Java(TM) SE Runtime Environment (build 1.7.0_07-b10)

UPDATE & Clarification:

  • The question is, WHY and WHAT EXACTLY is happening, not to "solve" the given example, i.e why does the first for-loop behave so weirdly, using 2x more CPU and blocking all threads of the JVM.
  • The example code terminates and gives the correct result.
  • The timer is just for demonstration, the problems occurs with or without it.
  • The limit of int is way above 2,000,000,000.
  • The problem affects all tested JVMs so far.
  • JProfiler and other debugging tools are interrupted/stalled during the first for-loop as well.
like image 452
Lukas N.P. Egger Avatar asked Jun 20 '26 01:06

Lukas N.P. Egger


1 Answers

It is because of the the optimizing compiler (probably trying to unroll the loop). It runs on a separate thread and that is why you see 200% CPU utilization. If you create a method out of the first loop and run it twice the second time it works as expected.

Try running your JVM like this:

java -Xint Main

That options disables the HotSpot compiler. In my case the timer thread prints on every second with no pauses.


If you run with java -XX:+PrintCompilation Main you will see that the compiler prints "made not entrant" in the middle of the first loop.

    79    6             java.lang.String::lastIndexOf (52 bytes)
    90    1 %           test.Main::main @ 33 (141 bytes)
    timestamp=Thu Feb 14 12:10:40 PST 2013
    timestamp=Thu Feb 14 12:10:41 PST 2013
    timestamp=Thu Feb 14 12:10:42 PST 2013
    timestamp=Thu Feb 14 12:10:43 PST 2013
    timestamp=Thu Feb 14 12:10:44 PST 2013
    13202    1 %           test.Main::main @ -2 (141 bytes)   made not entrant
    timestamp=Thu Feb 14 12:10:53 PST 2013
    Result: 1.80143985E16
    13202    2 %           test.Main::main @ 85 (141 bytes)
    timestamp=Thu Feb 14 12:10:54 PST 2013
    timestamp=Thu Feb 14 12:10:55 PST 2013

Swap the loops and it prints "made not entrant" between the two loops.

    72    6             java.lang.String::lastIndexOf (52 bytes)
    85    1 %           test.Main::main @ 33 (141 bytes)
    timestamp=Thu Feb 14 12:12:38 PST 2013
    timestamp=Thu Feb 14 12:12:39 PST 2013
    timestamp=Thu Feb 14 12:12:40 PST 2013
    timestamp=Thu Feb 14 12:12:41 PST 2013
    15415    1 %           test.Main::main @ -2 (141 bytes)   made not entrant
    Result: 1.80143985E16
    15415    2 %           test.Main::main @ 88 (141 bytes)
    timestamp=Thu Feb 14 12:12:42 PST 2013
    timestamp=Thu Feb 14 12:12:43 PST 2013
like image 95
jdb Avatar answered Jun 21 '26 13:06

jdb