深入分析java web 技术内幕_笔记_七

jvm体系和工作方式
1.jvm体系结构
(1).何为jvm:
<1>jvm全称是 java虚拟机 ,它通过模拟一个计算机来达到一个计算机所具有的的计算功能

<2>什么是指令集?就是cpu用来计算和控制计算机系统的一套指令集合。只要符合class文件规范的字节码都可以被JVM解析执行,这个指令集我们称为为JVM字节码指令集

<3>java虚拟机与实体机的不同
[1]java虚拟机只是一个抽象规范,其抽象规范在《The Java virtual Machine Specification》中描述

[2]其具体实现是不同的厂商按照这个抽象规范用软件或者软件和硬件结合的方式在相同或不同的平台实现

[3]每个运行中的java程序都是一个JVM实例
(2).JVM体系结构详解
<1>jvm的结构基本上是由4部分组成:类加载器、执行引擎、内存区、本地方法调用

<2>类加载器:在JVM启动时或者在类运行时将需要的class加载到jvm中(每个类型都对应一个Class类型的实例,这个实例被存放在java的堆中)

<3>执行引擎:负责执行class字节码,相当于实体机的cpu。其作用只是解析jvm字节码命令并得到执行结果,至于具体采用什么方式去得到这个结果则由jvm厂商决定(java虚拟机规范详细定义了执行引擎遇到每条字节码指令应该执行什么,得到什么结果)(执行引擎是执行一条条代码(一个个方法)的流程,而每一个java线程都是一个执行引擎的实例,一个java进程就是一个jvm实例,而一个jvm中包含多个java线程,也就是执行引擎的实例,这些执行引擎实例包括执行用户代码的,jvm内部程序的(java垃圾回收))

<4>Java内存管理:将内存划分为若干区域以模拟实际机器上的存储、记录、和调度功能模块。实际上每个jvm实例会有一个方法区、java堆、java栈、PC寄存器(与寄存器有什么区别?只是模拟实际机器上的寄存器的内存区域?)、本地方法区。其中java堆或方法区是所有线程(是不是所有这个jvm实例进程中的线程?)共享的。每一以执行引擎实例(java线程)都会被创建时都会创建一个java栈和一个PC寄存器,java栈用于存储该线程中方法的调用状态,包括方法中的参数,方法的局部变量,方法的返回值,运算的中间结果等等。而PC寄存器则指向即将执行的下一条指令

<5>本地方法调用:调用C或者C++的代码,返回结果
2.JVM工作机制:
(1)机器如何执行代码:通过机器执行代码类比,java代码通过编译成JVM语言来执行,通过指令集完成运算,指令集中包含具体的运算种类(操作码),运算需要的数据(操作数),从哪里获取操作需要的数据(操作数),而不同的存取方式将指令划分成 一地址指令、二地址指令等N地址指令,并且响应的指令集由对应的架构实现。(也就是说将代码根据规范转换成对应的指令,而通过这些指令去完成运算,而指令的具体实现则由对应实现者决定?)

(2)JVM为何选择基于栈的架构:
<1>JVM执行的字节码时基于栈的结构,也就是所有操作数必须先进栈,然后根据指令中的操作码选择弹出若干个元素进行计算后将结果压入栈中。
<2>JVM设计基于栈的理由:
[1]由于JVM要设计成平台无关的,所以必须保证没有寄存器或者很少寄存器的机器上也同样能操作
[2]使得比那以后的class文件更紧凑(使得如网络传输class字节码的应用场景由更高效率)
[3]自己的理解:也就是使用寄存器其实性能更高(时间?),但是比较消耗空间(不利于传输),但是由于跨平台的需要和减少class文件的数据量的需要,使用栈。
(3)执行引擎的架构设计:JVM为每一个线程(对应到一个执行引擎)创建一个java栈,而线程中每执行一个新的方法就会创建一个新的栈帧(栈帧应该是栈的一部分?),该栈帧则包含该方法的一些原信息,如方法中定义的局部变量,常量池的解析、正常方法的返回和异常处理机制等。而方法区和Java堆则存储所有线程共享的一些数据,如常量代表的数据,这个数据指向的实例化对象等

(4)执行引擎的执行过程:书中以一段简单代码的执行为例:PC寄存器中保存当前执行的函数(毎执行完一行都会修改?),局部变量去保存当前方法的局部变量(应该在各个方法的栈帧中?),而运算则是通过操作栈进行(操作数进栈,根据操作码将操作数出栈计算,并将最后结果进栈,在重新存到局部变量区,或再次运算时将结果出栈),另外还要注意的是,最后一条return指令执行后,方法的局部变量区的值将全部释放,PC寄存器将被销毁(一个线程一个PC寄存器?),这个个方法对应的栈帧将消失。(每个栈帧一个局部变量区,一个操作栈,但是一个栈只有一个PC寄存器)

(5)JVM方法调用栈:
<1>Java方法调用分为两种:一种是java方法调用,另外一种的本地方法调用(用c或C++实现的本地代码)
<2>java方法调用
[1]调用新的方法的话将创建栈帧(局部变量区,操作栈,其他栈帧数据等),并将PC寄存器清0(也就是指向当前调用方法的第一行)
[2]调用完毕后当前栈帧的操作栈的栈顶元素作为返回值,这个栈帧被撤销,PC寄存器恢复为调用方法的下一条指令的地址

[3]当执行的return指令后java栈中没有栈帧,这个栈将被取消(最后一条return指令?)
3.总结
[1]JVM的设计非常复杂,未经充分的“预热”的程序对测试结果可能由影响,包括JVM执行字节码时如何自动优化这些字节码,并编译成本地代码(机器码),如某个方法执行的次数到达一个阀值时,JIT就会吧这个方法编译为本地代码(也就是,除了在编译时的优化使得编译后的代码和源代码不一定完全相同,执行字节码时的优化液会使得执行结果不同?)






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值