1.栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集
本地变量
栈操作
栈帧数据
2,jvm加载class文件的原理
1,装载:查找和导入class文件
2,链接:其中解析是可以选择的
(1),检查:检查载入的Class文件数据的真确性
(2),准备:给类的静态变量分配存储空间
(3),解析:将符号引用转成直接引用
3,初始化:对静态变量,静态代码块执行初始化工作
3,所有的java虚拟机实现必须在每个或接口首次主动使用时初始化,下面6种情形符合主动使用的要找
(1),当创建某个类的实例时,或者通过在字节码中执行new指令,或者通过不明确的创建,反射,克隆或反序列化时
(2),当调用某个类的静态方法时,即在字节码中执行invokeStatic指令时
(3),当使用某个类或接口的静态字段,或者对改字段赋值时。即在字节码中执行getStatic或putStatic时,用final修饰的静态字段除外,它被初始化为一个编译时的常量表大式
(4),当调用Java API中的某些反射方法时,比如,类class中的方法或java.lang.reflect包中的类的方法
(5),当初始化某个类的子类是即当初始化某个类似,要求它的超类已经初始化
(6),当虚拟机启动时某个被表明为启动类的类,即含有main()方法的那个类
4,java虚拟机为变量分配内存,设置默认值。但在到达初始化阶段之前,类变量都没有被初始化为真正的值,在准备阶段是不会执行java代码的
5,初始化<Clinit>
所有的类变量初始化语句中类型的静态初始化器都被java编译器收集在一起,放到一个特殊的方法中,称为类初始化方法。在类和接口的javaClass文件中,这个方法被称为"<Clinit>"。通常java程序无法调用<Clinit>方法的,只能被java虚拟机调用。
初始化一个类的过程包含一下两个步骤:
1,如果类存在直接超类的话,且直接超类没有初始化,则先初始化直接超链。
2,如果类中存在一个类初始化方法(<Clinit>)就执行此方法
6,初始化的顺序按照类变量初始化语句和静态初始化语句出现的顺序
7.如果一个类没有声明任何变量,也没有静态初始化语句,那么他就不会有<Clinit>()方法,如果类声明了类变量,但是没有明确使用类变量初始化语句或者静态初始化语句初始化它们,那么它们就不会有<Clinit>()方法