Java的执行过程也就是JVM从启动到退出的过程。JVM的运行是一个进程单元,可以用jps工具列举出正在运行的JVM 进程。在一个JVM进程中可以运行多个线程。
1. JVM 启动
当用java工具运行一个编译好的class文件的时候,比如下面的命令,我们就通过调用Test的main函数启动了一个JVM进程。并且传给main函数一个字符串数组{"reboot", "Bob", "Dot", "Enzo"}
- 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. (不懂,求解)
- 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);
- }
- }
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);
- }
- }
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)
public static void main(String[] args)
public static void main(String... args)
6. 卸载类对象
这是一个优化过程,是为了释放内存的,但是JVM说明书并不严格定义这一行为,这取决于具体实现的优化策略。
7. 程序退出
当下面的条件之一发生的时候:
1. 所有的非daemon线程都终止了
2. 某个线程调用了类Runtime或者System的exit方法
分享到:
相关推荐
Java程序与JVM生命周期的一致性** 程序生命周期与Java虚拟机生命周期是一致的。这意味着Java虚拟机进程从创建起的任务就是执行Java程序,直至程序正常退出或异常终止,此时JVM也会随之关闭。 #### 二、类的生命...
在Java虚拟机(JVM)中,对象的生命周期包含了多个阶段,这些阶段共同决定了一个对象从诞生到消亡的过程。以下是这些阶段的详细介绍: **创建阶段(Creation)** 在这个阶段,对象从无到有,主要经历以下几个步骤:...
4、JVM生命周期 5、三大流行的JVM 2.2、JVM体系结构 1、类加载器 2、执行引擎 3、运行时数据区 4、本地库接口 2.3、JVM内存参数调整及监控 1、JVM之内存调整 2、JVM监控工具之Jconsole 3、JVM监控工具之JProfile ...
从汇编角度理解本地变量的生命周期,有助于我们深入认识JVM的工作机制。本地变量(Local Variables)是在Java方法中声明的变量,它们的生命周期与方法的执行紧密相关。 本地变量的生命周期始于方法的调用,当方法被...
这些数据通常在类加载时创建,并且在整个JVM生命周期中保持不变。对于HotSpot虚拟机而言,这部分区域被称为“永久代”(PermGen space),而在JVM 8之后,已经被“元空间”(Metaspace)所替代,其物理内存空间不再...
JVM 生命周期 1. JVM 实例的诞生:当启动一个 Java 程序时,一个 JVM 实例就产生了。任何一个拥有 public static void main(String[] args) 函数的 class 都可以作为 JVM 实例运行的起点。 2. JVM 实例的运行:main...
"Java对象在JVM中的生命周期详解" Java对象在JVM中的生命周期是Java编程语言中一个非常重要的概念,它涉及到Java对象的创建、使用、释放和销毁整个过程。在JVM中,Java对象的生命周期可以分为七个阶段:创建阶段、...
JVM生命周期概述 JVM的生命周期从启动一个Java程序开始,具体步骤如下: 1. **启动**:通过`java`命令启动JVM实例,指定main-class参数来指定应用程序的入口。 2. **运行**:执行`public static void main(String...
这些内置的类加载器加载的类在JVM生命周期中不会被卸载。而用户自定义的类加载器加载的类,当它们的`Class`对象不再被引用时,可能会被卸载,以节省内存资源。 了解类加载机制对于优化性能、理解和解决类加载相关...
这些数据在类被加载后就存在,并在整个JVM生命周期内保持不变。 4. **程序计数器(Program Counter Register)**: 每个线程都有一个独立的程序计数器,用于记录当前线程所执行的字节码指令的位置。在多线程环境下,...
单例对象在整个JVM生命周期中存在,如果单例持有外部对象的强引用,即使外部对象不再使用,也无法被垃圾回收器回收。为避免这个问题,可以使用弱引用(WeakReference)或软引用(SoftReference)来引用外部对象,...
1. **JVM生命周期**:JVM的生命周期开始于main()方法的执行,并在程序正常退出或遇到无法恢复的错误时结束。 2. **类加载机制**: - 类加载过程包括加载、验证、准备、解析和初始化五个阶段。 - 加载:查找并加载...
在JVM生命周期方面,从启动一个Java程序到程序运行过程中,JVM实例与独立运行的Java程序相对应,具有进程级别的生命周期。 面向对象的知识点涉及UML表示法和设计模式。UML表示法小结中包括类图、顺序图、活动图和...
JVM生命周期与Java程序紧密关联,当程序启动时,JVM实例诞生,程序结束时,JVM实例也随之消失。 JVM的体系结构包括类装载子系统和运行引擎,前者负责加载具有特定名称的类或接口,后者执行加载类中的指令。JVM内部...
### Java虚拟机与Java程序的生命周期 #### 一、Java虚拟机(JVM)概述 Java虚拟机(JVM)是一种可以执行Java字节码的虚拟机。它为Java应用程序提供了一个独立于硬件平台的运行环境,使得Java程序可以在任何安装了JVM...
- JVM生命周期包括加载、验证、准备、解析、初始化、运行、垃圾收集和卸载。 - 体系结构包括类装载器子系统、运行时数据区、执行引擎、本地方法接口和本地方法库。 13. **Java跨平台原理** - Java程序跨平台得益...
在C/C++中调用Java代码,主要...总的来说,C/C++调用Java的核心在于理解和正确使用JNI接口,确保Java和C/C++之间的数据转换正确,以及正确地管理JVM生命周期。这不仅涉及到技术实现,也涉及到了跨语言编程的最佳实践。