浏览 9355 次
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2012-04-04
最后修改:2012-04-09
Java的执行过程也就是JVM从启动到退出的过程。JVM的运行是一个进程单元,可以用jps工具列举出正在运行的JVM 进程。在一个JVM进程中可以运行多个线程。 1. JVM 启动 当用java工具运行一个编译好的class文件的时候,比如下面的命令,我们就通过调用Test的main函数启动了一个JVM进程。并且传给main函数一个字符串数组{"reboot", "Bob", "Dot", "Enzo"} java Test reboot Bob Dot Enzo 2. 加载类Test 如果JVM发现Test类还没有被加载,就会调用class loader去加载这个类的class 文件。 加载类,就是说ClassLoader 利用它的defineClass 方法来从class文件构建Class对象。 ClassLoader 应该有如下的特征: 1. 对于同一个类名,ClassLoader 多次load得到的类对象应该是一样的。 2. 如果ClassLoader L1 委托ClassLoader L2去load类C,对于任意类型T,如果T是C的直接父类或接口,或者是C的属性的类型,或者是C的方法的参数的类型或者返回值的类型,那么L1和L2 load出来的T的类的对象应该是一样的。 load完成之后,就可以连接这些类型,让他们进入可执行状态。 3. 连接 Test: 验证 Verify, 准备 Prepare, 解析 (Optionally) Resolve 在执行main之前要先初始化这个类,在初始化之前还要先连接,连接就是要验证,准备和解析。 验证就是检查语法和符号表,如果失败会报错。 准备就是要准备内存,主要为静态属性以及jvm内部需要的数据结构。这时只会将静态属性设置为默认值,但是静态代码块的执行不在这里,而是在初始化阶段。 解析就是检查这个Test对其他的对象或接口的引用,看看是不是那些引用的类和接口也被load进来了。没有的话就要load。解析过程是可选的,是因为你可以选择在load Test的时候load所有Test应用的类和接口,也可以在运行时真正用到的时候再load,也就是lazy load。 4.初始化 initialization 在main执行之前,必须先对类进行初始化。初始化类的变量,还有静态代码块。初始化的时候还要先初始化它的父类。每个类都有一个隐含的父类Object。 初始化过程发生在: 1. T是一个类,当T的一个实例创建的时候,也就是T t = new T(); 2. T的一个静态方法被调用的时候,也就是 T.staticField(); 3. T的静态属性被赋值的时候,T.staticField = o; 4. T的一个静态属性被使用的时候,也就是 Object o = T.staticField; 但是它不是常量。 5. T is a top level class , and an assert statement lexically nested within T is executed. (不懂,求解) class Super { static { System.out.print("Super "); } } class One { static { System.out.print("One "); } } class Two extends Super { static { System.out.print("Two "); } } class Test { public static void main(String[] args) { One o = null; Two t = new Two(); System.out.println((Object)o == (Object)t); } } 输出: Super Two false One没有被初始化,因为没有被调用过,Super在Two之前初始化。 class Super { static int taxi = 1729; } class Sub extends Super { static { System.out.print("Sub "); } } class Test { public static void main(String[] args) { System.out.println(Sub.taxi); } } 输出: 1729 Sub没有被初始化,因为taxi实际上上Super的属性。Sub没有静态属性被使用,所以不被初始化。所以不要在子类里面初始化父类的静态变量。 因为Java程序是多线程的,所以初始化过程需要同步synchronize,这是由jvm负责的。 Class对象有可能处在下面的状态之下: 1. 验证和准备好了,但还没有初始化 2. 正在被某个线程初始化中 3. 初始化好了,可以运行了 4. 错误状态,初始化失败 5. 调用 Test.main 初始化好之后,就开始调用Test.main。这个main方法必须得是public, static, and void. public static void main(String[] args) public static void main(String... args) 6. 卸载类对象 这是一个优化过程,是为了释放内存的,但是JVM说明书并不严格定义这一行为,这取决于具体实现的优化策略。 7. 程序退出 当下面的条件之一发生的时候: 1. 所有的非daemon线程都终止了 2. 某个线程调用了类Runtime或者System的exit方法 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-09
太监了?继续写呀。。
|
|
返回顶楼 | |
发表时间:2012-04-09
绝对的标题党
|
|
返回顶楼 | |
发表时间:2012-04-09
哇,好详细。真不愧,“详解” 。楼主大才,巨才
|
|
返回顶楼 | |
发表时间:2012-04-09
你又发到博客频道了,这里没有同步过来。以后还是直接整到论坛吧。
|
|
返回顶楼 | |
发表时间:2012-04-10
标题哥威武
|
|
返回顶楼 | |
发表时间:2012-04-12
第五点没人解答啊
|
|
返回顶楼 | |
发表时间:2012-04-12
继续写下去,免得别人看你笑话,前面写得不错,适合入门。 加油!!! |
|
返回顶楼 | |