繁体   English   中英

静态块与静态方法-初始化静态字段

[英]Static block vs static method - initializing static fields

出于好奇,我测量了静态块和静态方法初始化程序之间的性能。 首先,我在两个单独的java类中实现了上述方法,如下所示:

第一:

class Dummy {
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>();
    static {
        for(int i=0; i < 1000000; ++i) {
            lista.add(new Integer(i));
        }
    }
}

public class First {
    public static void main(String[] args) { 
        long st = System.currentTimeMillis();
            Dummy d = new Dummy();
        long end = System.currentTimeMillis() - st;
        System.out.println(end);    
    }
}

第二:

class Muddy {
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>();
    public static void initList() {
        for(int i=0; i < 1000000; ++i) {
            lista.add(new Integer(i));
        }
    }
}

public class Second {
    public static void main(String[] args) { 
        long st = System.currentTimeMillis();
            Muddy.initList();
            Muddy m = new Muddy();
        long end = System.currentTimeMillis() - st;
        System.out.println(end);    
    }
}

然后,我执行了这个小批处理脚本以对其进行100次测量,并将值放入文件中。 batchFile.bat First Second dum.res.txt

之后,我编写了这段代码来计算Dummy和Muddy的测量值的平均值和标准偏差。

这是我得到的结果:

First size: 100 Second size: 100
First       Sum: 132    Std. deviation: 13
Second      Sum: 112    Std. deviation: 9

而且在其他机器上也是如此...每次测试时。

现在我想知道,为什么会这样呢? 我检查了字节码,在对System.currentTimeMillis()的调用之间,Second.class还有一条指令(对static initList()的调用)。 他们俩都做同样的事情,但是为什么第一个要慢一些? 我真的不能仅仅通过查看字节码来推断原因,因为这是我第一次接触javap 我还不了解字节码。

我认为静态块版本比静态方法版本慢的原因可能是由于它们获得了不同的JIT优化...

请参阅此有趣的文章以获取更多有趣的信息: Java机密:是否解释静态块?

这是我对此的猜测:

您正在执行的初始化操作正在创建足以导致一个或多个垃圾回收的对象。

从静态块调用初始化时,它是在类初始化期间完成的,而不是在简单方法执行期间完成的。 在类初始化期间,即使堆的内容几乎相同,垃圾检测程序也可能比简单方法执行期间要做更多的工作(例如,因为执行堆栈更长)。

为了测试这一点,您可以尝试在Java命令中添加-Xms200m或其他内容。 这应该消除了您在初始化期间进行垃圾回收的需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM