java JVM虚拟机学习

20180719

1、 java 是由四方面组成的:java编程语言、java类文件格式、java虚拟机和java应用程序接口(java API)组成。

2、 java编译环境是:java源码文件通过java编译器(Eclipse,idear)等编译成java字节码文件(.class文件)

3、 javac编译器是官方JDK中提供的前端编译器,JDK/bin 目录下的javac只是一个与平台相关的调用入口,具体的实现是在JDK/lib目录下的tools.jar

4、 javac编译器源码编译

a、解析与填充符号表过程:解析主要包括词法分析和语法分析两个过程;

b、插入式注解处理器的注解处理过程;

c、语义分析与字节码的生成过程;

javac经过第一步的解析(语法分析和语法分析),会生成用来一颗描述程序代码语法结构的抽象语法树,每个节点都代表程序代码中的一个语法结构,

包括:包、类型、修饰符、运算符、接口、返回值、甚至注解等;而后不同的编译阶段都定义不同的访问者去处理改语法树(节点)。(访问者模式)

5、 解析与填充符号表:

a、解析包括:词法、语法分析

a1、词法分析是将源代码的字符流转换为标记(token)集合

标记是编程过程中最小元素,包含关键字、变量名、字面量、运算符(甚至一个".")等。

a2、词法分析是根据token序列构造抽象语法树的过程

抽象语法树是一种描绘程序代码结构的树形表达方式

语法结构(Construct)包括:包、类型、修饰符、运算符、接口、返回值、甚至注释等;

b、填充符号表

符号表是由一组符号地址和符号信息构成的表格,可以想象成哈希表中的K-V值的形势

符号表登记的信息在编译的不同阶段都要用到,如:

1) 用于语义检测和产生中间代码

2) 在目标代码生成阶段,符号表是对符号名进行地址分配的依据


6、 java整体机构

java基本API 和java基类 java标准扩展API 和 java标准扩展类(也就是我们写的程序)

java虚拟机

移值接口

适配器 java操作系统




可以看出,在java平台结构中,java虚拟机(JVM)处于核心位置,是程序与底层和硬件无关的关键

JVM 下方:是移植接口

移植接口是由 适配器 和java操作系统

适配器:依赖于平台的部分,------------jvm通过移植接口在具体的平台和操作系统上实现 。

JVM 上方:java的基本类库和扩展类库以及它们的API

7、 JVM 在它的生存周期中有一个明确的任务,那就是运行java程序因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。


8、 JVM 机制

a、类装载子系统:装载具有合适名称的类或接口

b、执行引擎:负责执行包含在已装载的类或者接口的指令。

9、 JVM包含:

方法区、Java堆、java栈、本地方法栈、指令计数器与其他隐含寄存器


10、简单理解的流程

Class文件-----> 类加载器子系统 <-------> 内存空间(方法区,java堆,java栈,本地方法栈) <------>垃圾回收器
↑ ↑ ↑
地址↑ 数据 ↑ 指令 ↑
↑ ↑ ↑
指令计数器 ↑ ↑
与其他隐含<--->执行引擎 <------->本地接口方法<----------本地方法库
寄存器


从这个结构中不难看出,class文件被jvm装载后,经过jvm的内存空间调配,最终由执行引擎完成clas文件的执行。

JVM关注:

java代码编译和执行的整个过程

JVM内存管理以及垃圾回收机制

11、java 代码编译是由java源码编译器来完成,流程如下

源代码--->(经过)词法分析器--->token流---->(经过)语法分析器---->语法树/抽象语法树---->(经过)语义分析器------->注解抽象语法树---->字节码生成器---->JVM字码节

12、java 字节码的执行是由JVM执行引擎来完成的

13、java代码编译和执行的整个过程包含了以下三个重要的机制:

a、java源码编译机制

b、类加载机制

c、类执行机制

14、java源码编译主要经过三个过程;

a、分析和输入到符号表

b、注解处理

c、语义分析和生成class文件

模式是:访问者模式


生成的class文件组成:

a、结构信息:包含class文件格式版本号以及各部分的数量和大小信息

b、元数据:对应的java源码中声明与常量的信息.包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池

c、方法信息:对应的java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

15、类加载机制:

JVM的类加载是通过classLoader以及其子类来完成的


这块可以查看classLoander那块整理信息

16、类执行机制

JVM是基于堆栈的虚拟机


JVM为每个新创建的线程分配一个堆栈(也就是对于一个程序来说,它的运行是通过对堆栈的操作来完成的)

堆栈以帧为单位保存线程的状态

JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作

JVM执行class字节码,线程创建后,都会产生程序计数器(PC)和栈(Stack)

PC:存放下一条要执行的指令在方法内的偏移量。

Stack:栈中存放一个个栈帧,每个栈帧对应每个方法的每次调用,而栈帧又是由局部变量区和操作数栈两部分组成。

局部变量区:存放方法中的局部变量和参数。

操作数栈:存放执行方法过程中产生的中间结果。

17、堆内存(heap)

new创建的对象的内存都会在堆中分配

存储的全部是对象,每个对象都包含一个与之对应的class信息。(class的目的是得到操作指令)

jvm只有一个heap区,被所有线程共享,不存放基本类型和对象引用,只存放对象本身。

堆的优劣势:堆的优势是可以动态的分配内存大小,生存期也不必事先告诉编译器,java的垃圾收集器会自动收取这些不在使用的数               

         据,但缺点是,由于要在运行时动态分配内存,存取速度慢。

18、栈内存(stack)

每个线程包含一个stack区,只保存基本数据类型的对象和自定义对象的引用(不是对象),对象都存放在heap区 ------生命周期和线程相同,一个线程对应一个java栈

每个栈中的数据(数据类型和对象引用)都是私有的,其他栈不能访问。

栈分为3部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)

  栈的优势劣势:存取速度比堆要快,仅次于直接位于CPU的寄存器,但必须确定的是存在stack中的数据大小与生存期必须是确定          

          的,缺乏灵活性。单个stack的数据可以共享。

stack:是一个先进后出的数据结构,通常保存方法中的参数,局部变量。

       在java中,所有基本类型和引用类型都在stack中储存,栈中数据的生存空间一般在当前scopes内

java栈空间不足了,程勋会抛出StackOverflowError异常,例如递归

19、方法区:

又叫静态区,跟堆一样,被所有的线程共享,方法区包含所有的class和static变量

方法区中包含的都是程序中永远的唯一元素。

19、PC寄存器:

类已经被加载了,实例对象、方法、静态变量都去了自己应该去的地方,那么问题来了,程序该怎么执行,那个方法先执行,那个方法后执行,

这些指令执行的顺序就是PC寄存器在管理,它的作用就是控制程序的执行顺序。

执行引擎当然就是根据PC寄存器的指令顺序,依次执行程序指令。

20、java宣传口号

一次编译,到处执行。

21、HelloWorld

java代码---->java字节码(class文件)---->java HelloWorld ----->加载配置(根据系统版本,寻求jvm.cfg文件)---->根据配置找到jvm.dll(jvm.dll文件则是jvm的主要实现)

-------->初始化jvm,获取JNI接口(JNI接口是java本地接口,通过JNI接口才能装载class文件,它还常用于和操作系统、硬件的交互)----->找到并执行main方法。

jvm.cfg:jvm的配置文件,位置 D:\Java\jdk1.7.0_80\jre\lib\amd64\jvm.cfg,通过jvm.cfg找到对应的jvm.dll文件

jvm.dll:jvm虚拟机的主要实现。位置: D:\Java\jdk1.7.0_80\jre\bin\server\jvm.dll

JNI接口:java本地接口。JVM怎么从硬盘上找到这个文件并装载到JVM里呢,就是通过JNI接口(它还常用于java与操作系统、硬件交互),找到class文件后并装载进JVM,然后找到main方法,最后执行

22、JVM配置参数分为三类参数: -----------这块的细学

a、跟踪参数

b、堆分配参数

c、栈分配参数


23、垃圾回收器的算法:

a、stop the world :执行某一个垃圾回收器算法的时候,JVM为了垃圾回收,会暂停java应用程序,等垃圾回收完成后,再继续运行。尽可能的减少stop the world的时间,就是我们优化jvm的主要目标。


b、引数算法:各个对象的引用个数,为0清楚

c、标记清除:标记可达不可达(存活/不存活),从GC Root遍历他们,清除不可达的内存

d、标记压缩:标记清除的算法上添加压缩

e、复制算法:把内存一分为二,只使用其中的一份,垃圾回收的时候,将正在使用的存活的复制到另一份空白的内存中,最后将正在使用的内存空间对象清除,完成垃圾回收。


24、垃圾回收器:

java堆内存结构包括:新生代和老年代,其中新生代由一个eden(伊甸区)和两个幸运区(s0 和 s1两个区)组成。两个幸运区是完全对称的,没有任何差别,也可以称作from区和to区

a、串行回收器:单线程,新生代复制算法,老年代标记压缩算法。串行收集器是最古老最稳定的收集器

b、并行回收器:多线程回收器

b1、ParNew回收器:这个回收器只针对新生代进行并发回收,老年代依然使用串行回收。回收算法依然和串行回收一样,新生代使用复制算法,老年代使用标记压缩算法

b2、Parallel回收器:依然是并行回收器,但这种回收器有两种配置,一种类似于ParNEW:新生代使用并行回收、老年代使用串行回收。它与ParNew的不同在于它在设计目标上更重视吞吐量,可以认为在相同的条件下它比ParNew更优

Parallel回收器另外一种配置则不同于ParNew,对于新生代和老年代均适应并行回收

c、CMS回收器:并发、标记、清除

程序与垃圾回收器同步执行。

步骤大致为:应用程序线程-->初始标记-->并发标记-->重新标记

 




 

 posted on 2018-07-25 10:21  风凌月歌  阅读(67)  评论(0编辑  收藏  举报