关于JIT的一个非常奇怪的表现

时间:2014-06-19 06:28:34

标签: java performance nio

当我调试我的应用程序时,我终于找到了问题。我可以重现它,但我不知道它为什么会发生。这是整个代码:

public static MappedByteBuffer map(File file, long length) throws IOException {
    RandomAccessFile raf = new RandomAccessFile(file, "rw");
    try {
        if (length > 0) {
            raf.setLength(length);
        }
        try {
            return raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length());
        } catch (IOException e) {
            System.gc();
            System.runFinalization();
            return raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length());
        }
    } finally {
        raf.close();
    }
}

public static void main(String[] args) throws IOException, InterruptedException {
    long t = System.currentTimeMillis();
    MappedByteBuffer mbb = map(new File("temp.mmp"), 1024L * 1024 * 1024);

    System.out.println("load " + (System.currentTimeMillis() - t));//*
    for (int i = 0; i < 2014L * 1024 * 1024; i++) {}//*
    int d = 0;
    for (int j = 0; j < 10; j++) {
        t = System.currentTimeMillis();
        mbb.position(0);
        mbb.limit(mbb.capacity());

        for (int i = 0; i < mbb.capacity(); i++) {
            d += mbb.get();
        }
        System.out.println(j + " " + (System.currentTimeMillis() - t));
    }
    System.out.println(d);
}

输出结果为:

load 3
0 3429
1 3443
2 3203
3 3197
4 3203
5 3194
6 3247
7 3216
8 3211
9 3201
-1073741824

在注释掉标有//*的两行后,输出为:

0 782
1 804
2 539
3 557
4 545
5 558
6 546
7 546
8 545
9 557
-1073741824

我在JDK 6/7/8和Windows7 64 OS下测试过,没有区别。但是在linux / CentOS下,问题就消失了。这是一个Java bug吗?或者我做错了什么。谢谢你的帮助。

经过深入研究,我了解到这是关于JIT的事情。但我还是不知道为什么。

新的测试代码:

public static void main(String args[]) {
    System.out.println("a");//1
    for (int i = 0; i <   1073741824; i++) {}//2
    {
        long d = 0;
        long t = System.currentTimeMillis();
        for (int j = 0; j < 40; j++) {
            for (int x = 0; x < 1073741824; x++) {
                d += 1;
            }
        }
        System.out.println(d + " " + (System.currentTimeMillis() - t));
    }
    {
        long d = 0;
        long t = System.currentTimeMillis();
        for (int j = 0; j < 40; j++) {
            for (int x = 0; x < 1073741824; x++) {
                d += 1;
            }
        }
        System.out.println(d + " " + (System.currentTimeMillis() - t));
    }
}

输出是:

a
42949672960 792
42949672960 1563

评论/取消注释// 1或// 2的行将影响结果。奇怪的事情。

0 个答案:

没有答案