jvm面试题(四)

参考《深入理解JVM》这本书,总结一下面试中常备问到的问题

14.Class文件结构
1.Class文件是一组以8位字节(1byte = 8bit)为基础单位的二进制流,中间没有任何分隔符,遇1个字节以上的数据,采用高地址对应低字节来分割存储。
2.class文件从前到后依次是
魔数、版本号、常量池计数、常量池、访问标识、类索引、父类索引、接口计数、接口表、字段计数、字段表、方法计数、方法表、属性计数、属性表。
3.常量池从1开始计数,存储两样东西:字面量(Literal)和符号引用。字面量可以理解为常量(文本字符串、声明为final的变量)符号引用则包括以下几种:类和接口的全限定名、字段的名称和描述(字段可以理解为在class内,方法外声明的那些变量)、方法的名称和描述。
4.class中字符串、方法名的长度(占用byte的个数)用一个2字节的int来表示,即方法名和字符串最大长度为 2^16 * 1字节 = 64KB 也就是说,超过这个长度的方法名或者字符创(”xxxxx”)将无法编译
5.访问标识
占两个字节,用来标识是否 public abstract interface final 注解 枚举  等等 
6.类索引、父类索引
确定类的全限定名和父类的全限定名
7.字段… 这段以后再总结吧


15.类加载时机、什么时候类会加载
类在内存中的整个生命周期包括
加载
链接: 验证、准备、解析
初始化
使用
卸载
除解析外所有步骤依次执行,解析可能会发生在初始化之后(多态,动态绑定)


什么时候会加载?
1.遇到***指令的时候,即new对象了,调用类静态字段(fina定义的除外且有初值的除外 )、静态方法
2.反射调用
3.初始化一个类时需要先初始化其父类
4.jvm启动时加载的包含main()的那个类
5.jdk1.7中反射调用方法。。。没看懂。。。


16.类加载过程
1.通过一个类的全限定名获取定义这个类的二进制字节流
  包括:.class 、jar、 网络、 甚至实时生成(动态代理 java.lang.reflect.Proxy)、其他文件(jsp)…
2.将这个字节流所代表的类的静态数据结构存储在方法区中(转换成了动态结构)
3.在内存中生成一个代表该类的java.lang.Class对象,作为方法区中所有访问该类的数据访问入口


17.类验证过程

1.文件格式验证

Class文件是否符合规范,当前虚拟机版本是否能处理

2.元数据验证

进行语义分析:是否有父类、是否实现了所继承的抽象类中所有方法…

3.字节码验证

通过数据流和控制流分析,语义是合法合理的,进一步的语义分析。(一个int的值没有被当成lang来写入)

4.符号引用验证

发生在将符号引用转换为直接应用的时候(解析阶段)用来检查权限,以及是否能成功解析


18.类的准备阶段

正式为类变量分配内存并设置变量初始值(0和null),只包括的类变量(static修饰),不包括实例变量


19.类的解析

解析阶段是将常量池内的符号引用替换为直接引用的过程

解析的动作针对于:类或接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符

符号引用:用一组符号(字符串)来描述所引用的目标,符号可以使任何形式的字面量,符号引用与jvm的内存布局无关,此时类可以没有加载到内存中

直接引用:可以使直接指向目标的指针、相对偏移量或一个能间接定位到目标的句柄,直接引用与内存布局相关,此时类一定已经加载到内存中了

20.类的初始化

真正开始执行类中定义的java程序代码,编译器收集类中所有变量的赋值语句和静态语句块合并成<clinit>方法(执行该方法前一定要执行父类的方法,所以所有类中最先执行的<clinit>方法一定是java.lang.Objer)并执行



猜你喜欢

转载自blog.csdn.net/TRUE_LOVE1314/article/details/52263264
今日推荐