JVM和类

调用Java命令运行Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序启动了多少条线程,创建了多少个变量,它们都处于该Java虚拟机进程里,共享该JVM进程的内存区。当系统出现以下几种情况时,JVM进程将被终止:

  • 程序运行到最后正常结束;
  • 程序运行到使用System.exit()或Runtime.getRuntime.exit()代码结束程序;
  • 程序运行过程中遇到未捕获的异常或错误而结束;
  • 程序所在的平台强制结束了JVM进程。

类的加载

当程序主动使用某个类时,如果该类还没有被加载到内存中,系统会通过加载、连接、初始化这三个步骤来对该类进行初始化(如果没有意外,JVM将会连续完成这三个步骤,所以有时也会把这三个步骤统称为类的加载或初始化)。

类的加载是指将类的class文件读入内存,并为之创建一个java.lang.Class对象(注意并不是目标类的对象)。也就是说当程序中使用任何类时都会为之创建一个java.lang.Class对象。

类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是Java程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。

通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有如下几种数据来源:

  • 从本地文件系统加载class文件;
  • 从jar包中加载class文件;
  • 通过网络加载class文件;
  • 把一个Java源文件执行动态编译,并执行加载。

java通常无需等到“首次使用”该类时才加载该类,Java虚拟机允许系统预先加载某些类。

类的连接

当类被加载后,系统会为之生成一个对应的Class对象,接着就会进入类的连接阶段。

类的连接阶段负责把类的二进制数据合并到JRE中。类的连接又可以分为如下三个阶段:

  • 验证:验证阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致;
  • 准备:类的准备阶段则负责为类的静态属性分配内存,并设置默认初始值;
  • 解析:将类的二进制数据中的符号引用替换成直接引用。(关于符号引用和直接引用我觉得这里说的非常明白)

类的初始化

在类的初始化阶段,虚拟机负责对类进行初始化,主要是对静态属性进行初始化。在java类中对静态属性进行初始化有两种方式:

  • 声明静态属性时指定初始值;
  • 使用静态初始化块为静态属性指定初始值。

进行初始化时,JVM会按语句在程序中的排列顺序依次执行初始化。如下面的代码,最终b的值为9。

package com.zhyea.test;

public class Test {

    static{
b=6;
} static int a = 0;
static int b = 9; }

JVM对类进行初始化时包含如下步骤:

  • 假如这个类还没有被加载和连接,程序先执行加载并连接这个类;
  • 假如该类的直接父类还没有被初始化,则先初始化其直接父类;
  • 假如类中有初始化语句,则系统依次执行这些初始化语句。

根据如上步骤可以看出来,当程序主动使用任何一个类时,系统会保证该类以及所有父类都会被初始化。

类初始化的时间

系统开始初始化类或接口的时间包括一下6种情况:

  • 创建类的实例;
  • 调用某个类的静态方法;
  • 访问某个类或接口的静态属性,或为该静态属性赋值;
  • 通过反射方式来创建某个类或接口对应的java.lang.Class对象,如使用Class.forName(“Person”);
  • 初始化某个类的子类。初始化子类时,所有的父类都会被初始化;
  • 直接使用java命令来运行某个类时。

需要一提的是final修饰的静态属性,如final修饰的静态属性在编译时就得到了属性值,那么该静态属性就会被当作常量不会被初始化(类的编译做了哪些事情呢,这里需要考虑下)。如下面这种情况:

final static int MON = 1;

final修饰的静态属性未能在编译时得到属性值,那么就会被初始化,如下面这种情况:

final static int TUE = 1+1;

还值得一提的就是ClassLoader的loadClass方法并不会执行类的初始化,而是只执行了类的加载。

最新文章

  1. angular源码分析:$compile服务——指令的编写
  2. Nginx-->基础-->理论-->nginx进程模型
  3. IIS负载均衡ARR路由请求到ARR服务器和处理服务器
  4. WPF学习笔记(一):数据绑定之元素到元素绑定
  5. size_t总结
  6. 新浪微博客户端(3)-封装UIBarButtonItem
  7. WPF 基础面试题及答案(一)
  8. SVG 2D入门5 - 颜色的表示
  9. PHP中的抽象类和接口
  10. TaskUtil多线程与定时任务
  11. sublime text snippet代码片断
  12. javascript中的一些基本方法收藏
  13. MySQL Crash Errcode: 28 - No space left on device
  14. java错误分类
  15. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
  16. 【转】Windows Server 2016 安装 IIS 服务时提示指定备用源路径
  17. Eclipse下使用Git
  18. Docker镜像构建(五)
  19. 第93天:CSS3 中边框详解
  20. Error: registers may not be the same -- `strexb r3,r2,[r3]'

热门文章

  1. 160808、Java的不同版本:J2SE、J2EE、J2ME的区别
  2. python中pip工具的安装与使用
  3. nodemailer发送邮件各个服务器接口
  4. responsive and functional programming RxJava
  5. 传说中的MATLAB1.0(1984年DOS界面182K、运行良好)附下载
  6. 四.mysql演示银行转账
  7. PyMongo的使用(转)
  8. Python(数据库安装与基本语句)
  9. sql server always on 2014安装配置
  10. Win7中的IIS配置asp时出现“出现403 文件夹禁止訪问错误”!