这两个问题《深入理解Java虚拟机》一书中均有解答。
(1)方法区用于存储被虚拟机加载的类型信息、常量、静态变量等信息。在JDK8以前,人们习惯将方法区称为永久代。这是因为方法区曾经是与Java堆连在一起的,而Java堆基于分代收集理论设计,方法区中确实也比较少出现垃圾收集,故有了“永久代”一名。到了JDK8,“永久代”的概念被摒弃,方法区在内存上不再与Java堆连续,而是与JRockit等虚拟机一样,将方法区放入元空间(Oracle希望能够整合JRockit和HotSpot两款虚拟机的优势,但是方法区相差过大。我认为这是放弃永久代的主要原因)
(2)静态变量是在类加载的时候完成初始化的,而普通变量是随着类对象的创建完成初始化的。
对象的创建有以下几步:
- 检查常量池中是否有一个类的符号引用,以及符号引用的类是否被加载;
- 为新生对象分配内存
- 内存分配完成后,虚拟机完成对内存空间的初始化(为null、false、0等值)
- 虚拟机对对象进行必要设置(对象头里面那些信息)
- 执行构造函数
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…