Month: September 2011

学习JVM原理-14.类装载时的Initialization并不总会执行

摘自《深入理解Java虚拟机》周志明著 代码里出现类名,未必就会初始化这个类. 不太严谨地说,只有你"用到"这个类时,类才会Initialize. 如果你只是点它的名,或者用的是它的父类,是不会Initialize的 直接看例子: class Bean { public static int beanValue = 123; static{ System.out.println("Bean inited"); } } main(){ new Bean(); // 会打印"Bean inited" } main(){ int i = Bean.beanValue;; // 会打印"Bean inited" } main(){ Class b = Bean.class; // 不会打印"Bean inited" } 再看下继承的情况 class SubBean extends Bean{ static { System.out.println("SubBean inited"); } public …

学习JVM原理-14.类装载时的Initialization并不总会执行 Read More »

学习JVM原理-13.类加载时的Preparation阶段

摘自《深入理解Java虚拟机》周志明著 Preparation阶段为static变量并设置初始值. 这里要区别变量是不是final.   1. public static final int abc = 123; 实际上对应两步:        a. 编译时即在constant pool里生成123这个字面量        b. 在prepration阶段再赋值为123   2. public static int abc = 123; 也可以分做两步:        a. preparation阶段先把abc赋值为0;        b. 在initialize阶段才赋值为123

学习JVM原理-11.类加载过程概述

摘自《深入理解Java虚拟机》周志明著 所谓 类加载,就是把字节码二进制文件(或流)弄到虚拟机内存里变成"类",并在其中进行验证和初始化的过程. 这个过程是在运行时完成的 具体有五个可能交叉进行的步骤:    1.Loading: 把ByteCode变成Runtime数据结构并将存储到Method Area(Heap里也会有个Class对象)    2.Verification: 你拿到的ByteCode可能不是java编译来的,因此可能包含不安全的指令或数据结构,这需要验证; 另外还要看看有没有java.lang.NoSuchFieldError之类的符号连接问题    3.Preparation: 为静态变量分配内存并设置初始值(0, null等)    4.Resolution: 把符号引用替换成与内存有关的直接引用,Verification中就会执行这一步以验证有没有符号连接问题    5.Initialization: 给静态变量赋值,并执行static块里的语句 这些步骤中有很多非显而易见,让你吃惊的东西.后文详述.

学习JVM原理-ClassLoader的Parents Delegation Model

摘自《深入理解Java虚拟机》周志明著 考虑到Class Loader之间的父子关系,JAVA建议采用 Parents Delegation Model来实现一个Class Loader: 装载一个类时,先把这件事委托给Parent Class Loader,Parent再委托给GrandParent,如此传递,直到根 Loader; 如果根Loader能够装载,则返回装载出的类,否则一级一级往下传,一旦载出来就返回 然而这个模式并不是硬性的约束,有两种情况违反了这个模式:   1. Bootstrap Loader需要装载一个SPI如JAXB的实现,但这些实现不在rt.jar里,因此需要调用System ClassLoader或者User Class Loader. (Thread.currentThred().getContextClassLoader() 就是干这个的)   2. 热替换如OSGi

学习JVM原理-四种Class Loader

摘自《深入理解Java虚拟机》周志明著 按ClassLoader的父子关系(概念上的父子关系,未必有类继承)排列 1.  Bootstrap ClassLoader 加载$JRE/lib下的类,如rt.jar里面的类 2.      Extension ClassLoader 加载$JRE/lib/ext下的类,如”sunjce_provider.jar”里面的类 3.          Application/System ClassLoader 加载ClassPath上指定的类库,它就是程序中默认的类加载器 4.              User ClassLoader

学习JVM原理-同一个ClassLoader加载的类,才是同一个类

摘自《深入理解Java虚拟机》周志明著 Object bean = anotherClassLoader.loadClass("Bean").newInstance(); //用自写的Class Loader装载Bean类并生成一个实例 System.out.println(bean instanceof Bean) // 答案将是false! 因为这里的Bean类是用系统默认的Classloader 装载的

学习JVM原理-10. 用javap分析bytecode文件中的Constant Pool

受教于《深入理解Java虚拟机》周志明著 直接看ByteCode文件会累死的,我们可以用JDK附带的javap -verbose A.class 来生成可读的信息. 下面就举个例子,看下这类信息中的Constant Pool部分 package pool; public class PlayConstant { private static final int DEFAULT_PLAYER_COUNT = 55; private String gameName; public Long getMoney(int playerCount) { long money = 10 * playerCount; return money; } } 一起来分析一下它的Constant Pool:    const #1 = class #2; // pool/PlayConstant –#2意思是它的值在Pool中的第#2个位置 const #2 = Asciz pool/PlayConstant; const …

学习JVM原理-10. 用javap分析bytecode文件中的Constant Pool Read More »

帮助识别文件类型: Magic Number/File Signature

文件类型一般是通过扩展名来识别的,但这个并不靠谱,因为扩展名可以瞎改 另一种作法是查看文件中特定位置(文件开头或少量偏移)的几个字节,因为大家有约定,一些特定的字节代表特定的类型. 这些字节就是 Magic Number,或称 File Signature 常见的Magic Number有:    http://en.wikipedia.org/wiki/List_of_file_signatures   50 4B 03 04        zip   CA FE BA BE      java class   FF FE              Byte-order mark for 16-bit Unicode text file  

学习JVM原理-9.ByteCode文件结构概述

摘自《深入理解Java虚拟机》周志明著 ByteCode类文件   1. 二进制文件   2. 以字节为单位存放有意义的数据,不以0/1为单位(怪不得叫字节码?)   3. 某段数据的意义由它所处的位置来定,并不像XML或JSON一样有元数据,如<name>abc</name>,ByteCode文件里只有"abc" 数据结构的范式(把一个类文件看作一栋楼)      1. 砖头: 无符号数     2. 房间: Table, 由无符号数搭建而成     3. Table下可以有Table     4. 整个类文件就是一个Table 主要数据成员:   1.Magic Number,表明当前文件是Class文件(固定为0xCAFEBABE)   2.minor_version 和 major_version,这决定了本class可以被什么版本的JRE运行   3.constant pool   4.access_flags, this_class,super_class, interfaces等   5.fields, methods   6.attributes,如字节码指令,exceptions,line number等