java虚拟机的运行原理

类加载器把一个类装入java虚拟机需要分三个步骤完成:分别为“装载”、“连接”、“初始化”,其中连接分为:验证、准备、解析过程;java源程序经过编译后形成字节码,字节码由java虚拟机解释执行,然后由java虚拟机的解释器解释成特定系统的机器码执行。

转载:查找和导入.class文件

连接:验证(确保Java类型数据格式正确并且是与java虚拟机使用),准备(为该类型分配它所需内存)、解析(负责把常量池中的符号引用转为直接引用)

初始化:给类变量赋予适当的初始值

1、装载:

描述:java虚拟机装载指定的CLASS文件

结果:形成这个CLASS类得实例对象

过程:JVM使用类装载器定位到相应的CLASS文件,然后读取这个CLASS文件(一个线性二进制数据流),将它传入java虚拟机中;紧接着虚拟机提取其中的类型信息,如:该类的类名、方法名、变量名、修饰符、方法的返回类型等。还有一个重要的常量池(常量池保存了该类型的所有常量,包括直接常量和对其他类型,字段,方法的符号引用)将这些信息保存在一个叫方法区的地方。最终形成CLASS类的实例,这个实例存放在内存的堆区。它成为了java程序与内部数据结构之间的接口,程序要访问该类型的信息,程序就调用该类型对应的CLASS实例对象的方法。简而言之:这个过程就是把一个类型的二进制数据解析为方法区中的内部数据结构,并在堆上建立一个CLASS对象的过程。

2、连接

描述:验证、准备、解析

结果:此类型是正确的

过程:

验证:确定类型符合java语言的语义,比如:final类不能有子类,final方法不能被覆盖,确保在类型和超类型之间没有不兼容的方法声明(比如两个方法拥有同样的名字,参数完全相同,但返回类型不同)。
准备:java虚拟机为类变量分配内存,设置默认值

解析:在类型的常量池中寻找类,接口,字段和方法的符合应用把这些符号引用替换成直接应用的过程

示例:

在类中定义了一个全局变量:final public static size=1;User u = new User();Java虚拟机为size分配内存,并赋默认值0.找到常量池中User类的引用,如果User类还没有被装载,则装载并且连接该类,然后将常量池中对User类的引用替换为直接引用。在此时User类并不会被初始化,因为还没有用它。

3、初始化

描述:初始化静态区,包括静态变量、静态代码块

结果:这个类型可以使用了

过程:可能会调用()方法,(这个方法只能够由java虚拟机调用)来初始化该类的静态变量。在调用这个方法前,必须确认该类的超类的() 方法已经被调用。java虚拟机将size的赋值为1.

4、使用该类代码:

4.1 User u = new User();(存放在内存的堆区)

创建了一个User类实例,实际上是通过这个类的CLASS实例实例化的。方法如下:

User u = (User)Class.forName("User").newInstance();为了方便,用C代替Class.forName("User")。
4.2u.setName("李文水"); u.setPwd("159");

调用该类的方法,为该类的变量赋值,Java虚拟机内部调用是这样的,通过方法区找到该方法,利用CLASS实例的如下方法调用:
c.getMethod("setName").invoke(u,"李文水");

4.3 String name = u.getName(); String pwd = u.getPwd();
与第二步类似,不同的是将取得的值分别赋给了变量name和pwd。关键是这个值保存在哪里?和实例对象一样,存放在堆区。这个时候我应该可以看出CLASS实例的作用了,它就是起个中间作用,将程序中的调用反应到堆区上数据的变化。

文章来源:http://zhidao.baidu.com/question/186854489.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值