Java代码作为一门跨操作系统的语言,最终是运行在JVM中的,所以对于JVM的理解就变得非常重要了。整体上,我们可以从三个方面来深入理解JVM。

  • Java代码的执行
  • 内存管理
  • 线程资源同步和交互机制

  Java程序运行在JVM上,JVM的运行状况对于Java程序而言会产生很大的影响,因此,掌握JVM中的关键机制对于编写稳定、高性能的Java程序很重要。首先,我们看看JVM规范定义的标准结构图:

JVM负责转载class文件并执行,因此,首先要掌握的是JDK如何将Java代码编译为class文件、如何转载class文件及如何执行class。将源码编译为class文件的实现取决于各个JVM实现或各种源码编译器;class文件通常有类加载器来完成加载;class的执行在Sun JDK中有解释执行和编译为机器码执行两种方式,其中编译为机器码又分为client和server两种模式。Sun JDK为了提升class的执行效率,对于解释执行和编译为机器码执行都设置了很多的优化策略。Java程序无需显示的分配和回收内存,因此JVM如何进行内存的分配和回收也是要关注的问题。JVM提供了多线程的支持,对于分布式Java应用而言,通常要借助线程来实现高并发,因此JVM中线程资源同步的机制及线程之间交互的机制也是需要掌握的。

Java代码的执行机制

Java源码编译机制

  JVM规范定义了class文件的格式,但并没有定义Java源码如何编译成class文件,各厂商自行实现编译器,例如Sun JDK中的javac。

下面简单介绍以上三个步骤:

  • 分析和输入到符号表(Parse and Enter):Parse过程主要是词法分析和语法分析,将代码字符串 ---> token序列 ---> 抽象语法树;Enter过程主要将符号输入到符号表,包括确定类的超类型和接口、添加默认构造器,符号输入符号表等
  • 注解处理(Annotation Processing):主要处理用户自定义的annotation,可基于annotation来生成附加代码或进行一些特殊的检查。
  • 语义分析和生成class文件(Analyse and Generate):Analyse过程主要基于抽象语法树进行一系列的语义分析。包括将语法树中的名字、表达式等元素与变量、方法、类型等联系到一起;检查变量使用前是否已声明;推导泛型方法的类型参数;...;将含有语法糖的语法树改为含有简单语法结构的语法树等。Generate过程主要是将实例成员初始化器收集到构造器中,将静态成员初始化器收集为();将抽象语法树生成字节码,采用后序遍历语法树,并进行最后少量代码转换(String相加转变为StringBuilder操作);最后从符号表生产class文件。

  class文件中并不仅仅存放了字节码,还存放了很多辅助jvm来执行class的附加信息,一个class文件包括了一下信息:

  • 结构信息:格式版本号及各部分的数量与大小的信息
  • 元数据:可简单对应Java源码中"声明"与"常量"的信息
  • 方法信息:可简单对应Java源码中"语句"与"表达式"的信息

  假设有如下一段简单的代码:

public class Foo {
    private static final int MAX_COUNT=1000;
    private static int count=0;
    public int bar() throws Exception {
        if(++count >= MAX_COUNT) {
            count = 0;
            throw new Exception("count overflow");
        }
        return count;
    }
}

// 执行javac -g Foo.java 编译此源码,之后通过 javap -c -s -l -verbose Foo 来参看编译后的class文件

// 类继承的超类/实现的接口的声明信息
public class Foo extends java.lang.Object
    SourceFile: "Foo.java"
// class文件格式版本号
minor version: 0
major version: 50
// 常量池,存放所有Field名称、方法名、方法签名、类型名、代码及class文件中的常量值
Constant pool:
const #1 = Method #7.#27; // java/lang/Object."<init>":()V
const #2 = Field  #6.#28; // Foo.count:I
const #3 = class  #29;    // java/lang/Exception
const #4 = String #30;    // count overflow
const #5 = Method #3.#31; // java/lang/Exception."<init>":(Ljava/lang/String;)V
...
const #34 = Asciz (Ljava/lang/String;)V;
{
    // 将符号输入到符号表时生成的默认构造器方法
    public Foo();
    ...
    // bar方法的元数据信息
    public int bar() throws java.lang.Exception;
    Signature: ()I
    // 对应字节码的源码行号信息
    LineNumberTable:
        line 9: 0
        line 10: 15
        line 11: 19
    // 局部变量信息,和方法绑定,接口没有方法体,所以ASM之类的在获取接口方法时,是拿不到方法中参数的信息
    LocalVariable:
        Start   Length  Slot    Name    Signature
        0       33      0       this    LFoo;
    Code:
        Stack=3, Locals=1, Args_size=1
        // 方法对应的字节码
        0:getstatic     #2; // Field count:
        ...
        // 记录有分支的情况
        StackMapTable: number_of_entries=1
        frame_type=29 /* same */
        // 异常处理器表
        Exceptions:
            throws java.lang.Exception
        ...
}

从以上可见,class文件是个完整的自描述文件,字节码在其中只占了很小的部分,源码编译为class文件后,即可放入jvm中执行。执行时jvm首先要做的是装载class文件,这个机制称为类加载机制。

《分布式Java应用之基础与实践》读书笔记四的更多相关文章

  1. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  2. 【鸟哥的Linux私房菜】笔记3

    正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...

  3. 【鸟哥的Linux私房菜】笔记2

    Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...

  4. 《鸟哥的Linux私房菜》笔记——02. 关于Linux

    Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...

  5. 《鸟哥的Linux私房菜》笔记——03. 磁盘分区

    Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...

  6. 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻

    连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...

  7. 【鸟哥的Linux私房菜】笔记

    操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...

  8. 《鸟哥的Linux私房菜》笔记——04. 简单命令行

    键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...

  9. 鸟哥的Linux私房菜学习笔记——文件权限与目录配置

    Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...

  10. 鸟哥的Linux私房菜学习笔记(1)

    2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...

随机推荐

  1. 【转】请求处理机制其二:Django中间件的解析

    Middleware 开始工作了 get_response 做的第一件事就是遍历处理器的 _request_middleware 实例变量并调用其中的每一个方法,传入 HttpRequest 的实例作 ...

  2. Office 365开发概述及生态环境介绍(一)

    原文于2017年3月13日首发于LinkedIn,请参考这个链接 离上一篇文章,很快又过去了两星期的时间.今天抓紧晚上的时间,开始了Office 365开发系列文章的第一篇,我会帮助大家回顾一下过去O ...

  3. java操作txt文本(一):遇到指定字符换行

    想法由来:有时查看网页源代码的css文件内容,竟是恼人的压缩后代码(不换行),如下图所示-- 它的可读性很差,所以写了下面这个简单的程序,实现自动换行. 适用条件:遇到指定字符换行(本例中遇到'}'换 ...

  4. Android 5.0(棒棒糖))十大新特性

    Android 5.0(棒棒糖))十大新特性 1. 全新Material Design设计风格 Android Lollipop全新的设计语言是受到了多种因素影响,是一种大胆的平面化创新.换句话说,谷 ...

  5. (转)关闭iptables和SELinux

    1. 关闭SELinux setenforce 0   #临时关闭 编辑/etc/selinux/config,找到SELINUX 行修改成为:SELINUX=disabled:     #永久关闭, ...

  6. 结队编程study

    ##今天针对study进行结队编程,我和搭档张佳慧刚开始误认为SystemBarTintManager,baseActivity是personalActivity跳转的下一个界面,因为这个代码个人中心 ...

  7. 任务一:零基础HTML编码练习

    任务目的 了解HTML的定义.概念.发展简史 掌握常用HTML标签的含义.用法 能够基于设计稿来合理规划HTML文档结构 理解语义化,合理地使用HTML标签来构建页面 任务描述:完成一个HTML页面代 ...

  8. Java 垃圾回收(GC) 泛读

    Java 垃圾回收(GC) 泛读 文章地址:https://segmentfault.com/a/1190000008922319 0. 序言 带着问题去看待 垃圾回收(GC) 会比较好,一般来说主要 ...

  9. RN 导入原有Xcode项目中,引入Pod依赖出现的问题与解决

    RN 导入原有Xcode项目中,引入Pod依赖出现的问题与解决 前言 最近学习React Native技术.将RN引入到原来Xcode项目中有一步:给原来Xcode项目添加所需要的Pod依赖 写好Po ...

  10. 第1章1zabbix快速入门

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; t ...