《分布式Java应用之基础与实践》读书笔记四
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应用之基础与实践》读书笔记四的更多相关文章
- 【鸟哥的Linux私房菜】笔记1
Linux是什么 从操作系统与cpu架构关系到linux Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...
- 【鸟哥的Linux私房菜】笔记3
正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...
- 【鸟哥的Linux私房菜】笔记2
Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...
- 《鸟哥的Linux私房菜》笔记——02. 关于Linux
Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...
- 《鸟哥的Linux私房菜》笔记——03. 磁盘分区
Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...
- 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻
连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...
- 【鸟哥的Linux私房菜】笔记
操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...
- 《鸟哥的Linux私房菜》笔记——04. 简单命令行
键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...
- 鸟哥的Linux私房菜学习笔记——文件权限与目录配置
Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...
- 鸟哥的Linux私房菜学习笔记(1)
2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...
随机推荐
- 【转】请求处理机制其三:view层与模板解析
进入 View 了 如果处理过程这时候还在继续的话,处理器会调用 view function.Django 中的 Views 不很严格因为它只需要满足几个条件: 必须可以被调用. 必须接受 djan ...
- spring循环依赖问题分析
新搞了一个单点登录的项目,用的cas,要把源码的cas-webapp改造成适合我们业务场景的项目,于是新加了一些spring的配置文件. 但是在项目启动时报错了,错误日志如下: 一月 , :: 下午 ...
- Linux之cut命令
cut 参数: -d 指定分隔符,与-f 一起使用,默认是空格.例如:-d“|” -f 指定取第几段的数据与-d一起使用 -c 以字符为单位取出固定字符区间 示例: 取不连续区间的内容的时候使用 ...
- 【C++】模拟实现auto_ptr
看了<Effctive C++>,里面提到用对象去管理资源,可以有效防止内存泄漏. 结合auto_ptr特性,稍微思考了一下,实现了一个简单的auto_ptr (因为代码量小,就不分文件了 ...
- React-Native 之 项目实战(三)
前言 本文有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关. 如文中内容对 ...
- exports和module.exports的区别
总结:exports是module.exports的指向. 1. module应该是require方法中,上下文中的对象 2. exports对象应该是上下文中引用module.exports的新对象 ...
- shiro使用教程
一.shiro是什么 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.不仅可以在Web项目中使用,在普通的项目中也是可以使用的 二.shiro可以做什 ...
- WebStorm里使用注意点
归纳一些我在使用webstorm里遇到的问题: 1.问题:文件出现红线,如图 解决方案:可能是由于语言版本的问题,改一下版本试试 2.快捷键:http://www.cnblogs.com/yeming ...
- webpack点滴记录
有了webpack..(不借助gulp/grunt)代码压缩 图片base64,解析less/sass coffee css压缩,MD5加密都帮你做了..还支持按需加载..还有热替换 webpack常 ...
- Android线程池使用终结版
有一段时间没写博文了,今天抽空总结一下,也希望能通过自己写的这些文章,加深理解的同时能帮 助在技术方面有疑点的朋友搞清楚个所以然来,由于经常会在网上或群里看到有朋友会问线程方面的 东西,就像我一个朋友 ...