Java类编译、加载、和执行机制

标签: java 类加载 类编译 类执行 机制


0.前言

个人认为,对于JVM的理解,主要是两大方面内容:

  • Java类的编译、加载和执行。
  • JVM的内存管理和垃圾回收机制。

本文主要是以概要的形式学习第一点:类的编译、加载和执行。关于内存管理机制请看另外一篇文章JVM的内存管理和垃圾回收机制


1. Java类的编译过程

这是由*.java源码文件转为 .class二进制字节码文件的过程。

我们编写好的源代码,就是
.java文件。使用“javac test.java”就可以编译test.java文件。

编译过程主要有三步:

  • 词法分析和输入到符号表
  • 注解处理
  • 语义分析和生成字节码

详细过程:

源代码文件*.java -> 词法分析器 -> tokens流 -> 语法分析器 -> 语法树/抽象语法树 -> 语义分析器 -> 注解抽象语法树 -> 字节码生成器 -> JVM字节码文件*.class

最后剩成的JVM字节码文件,使用命令“javap -c test”可以查看test.class的字节码信息,主要包含三项内容:

  • 结构信息:class文件相关信息。

  • 元数据:Java源码中的声明和常量信息。

  • 方法信息:Java源码语句和表达式对应的字节码。


2. 类加载机制

2.1 类加载器分类

类加载器其实也是Java类。有四大类:

  • 根加载器Bootstrap Class Loader

  • 扩展加载器Extension Class Loader

  • 系统应用加载器APP Class Loader

  • 用户自定义加载器Customer Class Loader

下面是各个类加载器的具体情况:

Java程序在执行前先要检查类是否已经被加载。

2.2检查过程

检查类是否已经被加载,从底层往上层依次检查各个加载器已经加载的类,顺序是系统应用类加载器、扩展加载器、根加载器,一旦发现被某个加载器加载过,则马上使用该类。如果一直找到最顶层的根加载器,发现类还没有被加载进JVM运行数据区的方法区,则接下来就要加载该类。

2.3类加载过程

加载过程和检查过程顺序相反,从上层往下层的顺序进行加载。从加载器检查自己的加载路径,找要加载的类,一旦找到类就进行加载。

注意:对每个加载器,最多只能加载一次系统绝对路径下的同一个类。对类而言,可以被不同加载器重复加载,只要你把类放到类加载器的加载路径下,就可以被那个加载器加载。


3. 类执行机制

类在被加载之后,接下来进行连接、初始化,然后才是使用,最后卸载。

3.1 连接

连接(linking)包括三个部分:

  • 验证verifying:验证类符合Java规范和JVM规范,和编译阶段的语法语义分析不同。

  • 准备preparing:为类的静态变量分配内存,初始化为系统的初始值。(不初始化静态代码块)。对于final static修饰的变量,直接赋值为用户的定义值。

  • 解析resolving:将符号引用(字面量描述)转为直接引用(对象和实例的地址指针、实例变量和方法的偏移量)

3.2 类初始化

初始化类的静态变量和静态代码块为用户自定义的值。非静态类在实例化类,在Java堆中创建对象的时候,才会进行初始化。初始化的顺序,和Java源码的从上到下顺序一致。注意:什么时候触发初始化?在类被Java程序“第一次主动使用”的时候,才会触发初始化操作(如果还没有加载,则会顺势触发类的加载过程)。

3.3内存分配

启动JVM后,操作系统就给JVM分配了内存空间,JVM自己由把得到的内存分为几块:

JVM是基于栈结构的体系结构来执行class字节码的,不同于windows和Linux基于寄存器结构。类的执行机制,主要是在Java栈上面完成。当一个线程被创建后,Java栈和PC寄存器就会被创建。Java栈由栈帧组成,调用一个方法,就会生成一个栈帧(可以理解为表示调用一个方法)。栈帧又由局部变量表、操作数栈和常量池引用组成。

执行的时候,每个线程都有一个Java栈,当前执行的栈称为当前栈。一个Java栈调用多个方法,则会push很多个栈帧,当前活动的栈帧称为当前栈帧。当前栈帧执行完毕之后,会把执行结果(如果有)压入到调用它的那个栈帧的操作数栈中,作为上一个栈帧的一个中间处理结果被调用,然后就会被pop出去。当所有调用的方法执行结束后,栈帧也就都pop掉没有了。

例如:执行代码

3.4 类具体的执行过程

本步骤由执行引擎Execute Engine来完成。执行引擎把字节码转为机器码,然后操作系统才可以真正调用,在硬件环境上执行代码。执行引擎的通过Java字节码解释器(一行一行解释字节码)和JIT(Just In Time)即时编译器(对热代码整段编译)来完成机器码的翻译工作。

JIT编译器的工作流程为:

JVM字节码 -> 机器无关优化 -> 中间代码 -> 机器相关优化 -> 中间代码 -> 寄存器分配器 -> 中间代码 -> 目标机器码生成器 -> 目标机器码

Java类编译、加载、和执行机制的更多相关文章

  1. java类的加载和执行顺序

    以前面试总会碰到涉及到类的执行过程的笔试题.下面记录我自己的测试结果: public class ClassA { public static ClassA classa = new ClassA() ...

  2. 【转】 java类的加载和执行顺序

    1.先执行Test类的静态代码块后执行Test类的main方法,说明要执行类的方法需要先加载这个类. 2.在创建ClassB的对象时,先去加载了父类ClassA.说明加载子类时如果没有加载父类,会先加 ...

  3. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  4. JVM(1):Java 类的加载机制

    原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...

  5. Java类的加载、链接和初始化

    一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...

  6. JAVA类的加载、连接与初始化

    JAVA类的加载.连接与初始化 类的声明周期总共分为5个步骤1.加载2.连接3.初始化4.使用5.卸载 当java程序需要某个类的时候,java虚拟机会确保这个类已经被加载.连接和初始化,而连接这个类 ...

  7. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

  8. java类从加载、连接到初始化过程

    类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个Class对象,存储在.class文件中,JV ...

  9. JAVA - 类的加载过程

    JAVA - 类的加载过程 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象 ...

  10. java 类的加载,链接,初始化

    本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...

随机推荐

  1. zabbix切换中文,监控图下方显示乱码,监控图X轴不显示时间问题解决(适用于所有版本)

    一.现象: abbix3.4安装好后添加zabbix图形,发现有好多方块 这是因为zabbix web程序缺少中文字体 二.解决方案1: 1.在windows系统找一个中文字体上传到服务器中,我这里找 ...

  2. SDN学习笔记

    SDN 什么是SDN SDN是一种框架和思想,核心诉求是通过软件控制网络,实现业务的自动化部署,为方便软件来控制网络,希望控制面和转发面是分离的. 例如,传统的交换机内部,由交换机负责具体的网络流量往 ...

  3. 高可用OpenStack(Queen版)集群-9.Cinder控制节点集群

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

  4. nginx keepalived 高可用方案(转)

    转自: https://www.cnblogs.com/leeSmall/p/9356535.html 一.Nginx Rewrite 规则 1. Nginx rewrite规则 Rewrite规则含 ...

  5. PHP使用Memcache来存储session 其他【转载】

    PHP使用Memcache来存储session 分类:PHP 时间:2015年3月30日 很多时候一个完整的系统可能运行在多个服务器上,如果这多个服务器之间需要共享session的话,那么PHP默认的 ...

  6. Objective-C中,类方法的getter和setter可以用点运算符吗?

    Objective-C中,对象实例property的getter和setter可以使用点运算符来操作,那么类方法的getter和setter可以使用点运算吗? 答案是肯定的. 看如下代码: #impo ...

  7. “Hello World!“”团队第七周召开的第三次会议

    今天是我们团队“Hello World!”团队第七周召开的第三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码 一 ...

  8. Java程序设计基础项目总结报告

    Java程序设计基础项目总结报告 20135313吴子怡 一.项目内容 运用所学Java知识,不调用Java类库,实现密码学相关算法的设计,并完成TDD测试,设计运行界面. 二.具体任务 1.要求实现 ...

  9. Task 6.3 场景调研

    1.背景: (1)典型用户:信息1303班王银凤 (2)用户的需求/迫切需要解决的问题:她们宿舍上网一直使用的是外网,一年400的一种“套餐”.这种是按小时计算的,在校的时间平均下来一天可以用7 . ...

  10. 软工1816 · Beta冲刺(3/7)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 协助后端完成历史记录接口.美食排行榜接口 完成食堂平面图的绘制 确定web端业 ...