yhef 发表于 2013-1-29 22:50:33

JVM笔记

"运行时包"阻隔不同ClassLoader加载的类之间互相访问

.class文件的校验过程
1:class文件的结构检查,比如必须以0xCAFEBABE开头,文件长度与声明长度是否匹配等。
2:数据类型的语义检查,比如:返回类型、final类的强制规则、参数个数是否合法。
3:字节码验证,字节码流代表java的方法(由操作码和操作数组成),栈桢
4:符号引用的验证,验证所关联(引用)的类、方法、字段是否正确,即使不正确也只会在真正调用的时候才抛相应的异常

一个线程创建一个Java栈,当调用一个方法时则压入一个栈桢到该线程的java栈中,方法返回时就弹出。
栈桢由三部分组成:局部变量区(参数、局部变量)、操作数栈和帧数据区

jvm规范中,int 0表示false,非0整数表示true; boolean [] ,则是用byte[]来标识

装载(查找并装载类型的二进制数据)
   装载阶段的三个基本动作:
   1:通过该类型的全限定名,产生一个代表该类型的二进制数据流
   2:解析这个二进制数据流为方法区内的内部数据结构
   3:创建一个标识该类型的java.lang.Class类的实例
-->
连接(验证(正确性)-->准备(为类变量分配内存地址,并为其初始化默认值)-->解析(将符号引用转换为直接引用)(可选))
-->
初始化(把类变量初始化为正确初始值)
初始化一个类包含两个步骤:
   1:如果存在直接超类,且直接超类还没初始化,就先初始化直接超类
   2:如果类存在一个类初始化方法,就执行此方法
   初始化接口并不需要初始化它的父接口



方法区和堆都可以是不连续的内存区

引用类型:
1:类类型
2:接口类型
3:数组类型

方法区存储类型信息、类(静态)变量

类型信息包括:
1:类型的全限定名
2:类型的直接超类的全限定名
3:类型是类类型还是接口类型
4:类型的访问修饰符public /abstract /final
5:任何直接超接口的全限定名的有序列表
....
x:该类型的常量池
x:字段信息
x:方法信息
x:除了常量以外的所有类(静态)变量
x:一个到类ClassLoader的引用
x:一个到Class类的引用


.class文件的大致结构:
1:魔数:0xCAFEBABE;快速区分某个class文件是否是Java class文件
2:minor_version和major_version;辅助版本号和主版本号
3:constant_pool.count和constant_pool;
4:access_flags
5:this_class
6:super_class
7:interfaces_count和interfaces
8:fields_count和fields
9:methods_count和methods
10:attributes_count和attributes

常量池:
1:CONSTANT_Utf8_info表
2:CONSTANT_Integer_info
3:CONSTANT_Float_info
4:CONSTANT_Long_info
5:CONSTANT_Double_info
6:CONSTANT_Class_info
7:CONSTANT_String_info
8:CONSTANT_Fieldref_info
9:CONSTANT_Methodref_info
10:CONSTANT_InterfaceMethodref_info
11:CONSTANT_NameAndType_info


主动使用的六种情形,将会导致类或接口的初始化:
1:创建某个类的新实例时(new\反射\克隆\反序列化)
2:调用某个类的静态方法时
3:使用类或接口的非常量静态字段,或对该字段赋值时(用getstatic/putstatic指令时),用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式
4:当调用Java API中的某些反射方法时,如Class中的方法或者java.lang.reflect包中的类的类方法
5:当初始化某个类的子类时
6:当虚拟机启动时某个被标明为启动类的类(即含有main()方法的那个类)


任何一个类的初始化都需要它的超类在此之前已经初始化,而接口,只有在某个接口所声明的非常量字段被使用时,该接口才会被初始化,而不会因为其子接口或子类的初始化而被初始化。

如果一个字段既是static的,又是final的,并且使用一个编译时常量表达式初始化,使用这样的字段,就不是对声明该字段的类的主动使用


GC种类:
1:引用计数,对象引用计数器
2:跟踪收集,图,标记并清除
3:压缩收集,程序-->句柄-->内存地址,移动碎块
4:拷贝收集,分配实际内存的2倍,同时使用的始终只有一块,当其中一块满的时候,停止应用程序,拷贝并整理碎片到令一块内存,切换工作的内存,再恢复程序
5:按代收集,把堆按对象的生命周期长短分成不同的代,GC最频繁地收集最年轻的代,如果对象多次没有被收集,则会标识为更高一代(生命周期更长)
页: [1]
查看完整版本: JVM笔记