`

JVM 生命周期

 
阅读更多

Java的执行过程也就是JVM从启动到退出的过程。JVM的运行是一个进程单元,可以用jps工具列举出正在运行的JVM 进程。在一个JVM进程中可以运行多个线程。
1. JVM 启动
当用java工具运行一个编译好的class文件的时候,比如下面的命令,我们就通过调用Test的main函数启动了一个JVM进程。并且传给main函数一个字符串数组{"reboot", "Bob", "Dot", "Enzo"}

Java代码
  1. java Test 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. (不懂,求解)

Java代码
  1. class Super {
  2. static { System.out.print("Super "); }
  3. }
  4. class One {
  5. static { System.out.print("One "); }
  6. }
  7. class Two extends Super {
  8. static { System.out.print("Two "); }
  9. }
  10. class Test {
  11. public static void main(String[] args) {
  12. One o = null;
  13. Two t = new Two();
  14. System.out.println((Object)o == (Object)t);
  15. }
  16. }
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);
}
}



输出:

Java代码
  1. Super Two false
Super Two false


One没有被初始化,因为没有被调用过,Super在Two之前初始化。

Java代码
  1. class Super {
  2. static int taxi = 1729;
  3. }
  4. class Sub extends Super {
  5. static { System.out.print("Sub "); }
  6. }
  7. class Test {
  8. public static void main(String[] args) {
  9. System.out.println(Sub.taxi);
  10. }
  11. }
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.

Java代码
  1. public static void main(String[] args)
  2. public static void main(String... args)
public static void main(String[] args)
public static void main(String... args)



6. 卸载类对象
这是一个优化过程,是为了释放内存的,但是JVM说明书并不严格定义这一行为,这取决于具体实现的优化策略。
7. 程序退出
当下面的条件之一发生的时候:
1. 所有的非daemon线程都终止了
2. 某个线程调用了类Runtime或者System的exit方法

分享到:
评论

相关推荐

    Java中类的生命周期

    Java程序与JVM生命周期的一致性** 程序生命周期与Java虚拟机生命周期是一致的。这意味着Java虚拟机进程从创建起的任务就是执行Java程序,直至程序正常退出或异常终止,此时JVM也会随之关闭。 #### 二、类的生命...

    JVM中对象的生命周期

    在Java虚拟机(JVM)中,对象的生命周期包含了多个阶段,这些阶段共同决定了一个对象从诞生到消亡的过程。以下是这些阶段的详细介绍: **创建阶段(Creation)** 在这个阶段,对象从无到有,主要经历以下几个步骤:...

    很入理解JVM体系

    4、JVM生命周期 5、三大流行的JVM 2.2、JVM体系结构 1、类加载器 2、执行引擎 3、运行时数据区 4、本地库接口 2.3、JVM内存参数调整及监控 1、JVM之内存调整 2、JVM监控工具之Jconsole 3、JVM监控工具之JProfile ...

    JVM详解之汇编角度理解本地变量的生命周期

    从汇编角度理解本地变量的生命周期,有助于我们深入认识JVM的工作机制。本地变量(Local Variables)是在Java方法中声明的变量,它们的生命周期与方法的执行紧密相关。 本地变量的生命周期始于方法的调用,当方法被...

    深入浅出jvm虚拟机视频大全(jvm性能调优+内存模型+虚拟机原理)

    这些数据通常在类加载时创建,并且在整个JVM生命周期中保持不变。对于HotSpot虚拟机而言,这部分区域被称为“永久代”(PermGen space),而在JVM 8之后,已经被“元空间”(Metaspace)所替代,其物理内存空间不再...

    JVM的相关概念.doc

    JVM 生命周期 1. JVM 实例的诞生:当启动一个 Java 程序时,一个 JVM 实例就产生了。任何一个拥有 public static void main(String[] args) 函数的 class 都可以作为 JVM 实例运行的起点。 2. JVM 实例的运行:main...

    Java对象在JVM中的生命周期详解

    "Java对象在JVM中的生命周期详解" Java对象在JVM中的生命周期是Java编程语言中一个非常重要的概念,它涉及到Java对象的创建、使用、释放和销毁整个过程。在JVM中,Java对象的生命周期可以分为七个阶段:创建阶段、...

    最新java面试专题01-JVM

    JVM生命周期概述 JVM的生命周期从启动一个Java程序开始,具体步骤如下: 1. **启动**:通过`java`命令启动JVM实例,指定main-class参数来指定应用程序的入口。 2. **运行**:执行`public static void main(String...

    Java虚拟机JVM类加载初始化

    这些内置的类加载器加载的类在JVM生命周期中不会被卸载。而用户自定义的类加载器加载的类,当它们的`Class`对象不再被引用时,可能会被卸载,以节省内存资源。 了解类加载机制对于优化性能、理解和解决类加载相关...

    java中jvm原理和实现

    这些数据在类被加载后就存在,并在整个JVM生命周期内保持不变。 4. **程序计数器(Program Counter Register)**: 每个线程都有一个独立的程序计数器,用于记录当前线程所执行的字节码指令的位置。在多线程环境下,...

    内存泄露从入门到精通三部曲之常见原因与用户实践1

    单例对象在整个JVM生命周期中存在,如果单例持有外部对象的强引用,即使外部对象不再使用,也无法被垃圾回收器回收。为避免这个问题,可以使用弱引用(WeakReference)或软引用(SoftReference)来引用外部对象,...

    java-面试题合集,基础,进阶

    1. **JVM生命周期**:JVM的生命周期开始于main()方法的执行,并在程序正常退出或遇到无法恢复的错误时结束。 2. **类加载机制**: - 类加载过程包括加载、验证、准备、解析和初始化五个阶段。 - 加载:查找并加载...

    Java编程思想学习笔记

    在JVM生命周期方面,从启动一个Java程序到程序运行过程中,JVM实例与独立运行的Java程序相对应,具有进程级别的生命周期。 面向对象的知识点涉及UML表示法和设计模式。UML表示法小结中包括类图、顺序图、活动图和...

    java虚拟机详解

    JVM生命周期与Java程序紧密关联,当程序启动时,JVM实例诞生,程序结束时,JVM实例也随之消失。 JVM的体系结构包括类装载子系统和运行引擎,前者负责加载具有特定名称的类或接口,后者执行加载类中的指令。JVM内部...

    Java虚拟机和Java程序的生命周期?

    ### Java虚拟机与Java程序的生命周期 #### 一、Java虚拟机(JVM)概述 Java虚拟机(JVM)是一种可以执行Java字节码的虚拟机。它为Java应用程序提供了一个独立于硬件平台的运行环境,使得Java程序可以在任何安装了JVM...

    java面试大全.doc

    - JVM生命周期包括加载、验证、准备、解析、初始化、运行、垃圾收集和卸载。 - 体系结构包括类装载器子系统、运行时数据区、执行引擎、本地方法接口和本地方法库。 13. **Java跨平台原理** - Java程序跨平台得益...

    在 C/C++ 中调用 Java

    在C/C++中调用Java代码,主要...总的来说,C/C++调用Java的核心在于理解和正确使用JNI接口,确保Java和C/C++之间的数据转换正确,以及正确地管理JVM生命周期。这不仅涉及到技术实现,也涉及到了跨语言编程的最佳实践。

Global site tag (gtag.js) - Google Analytics