1991年4月,由James Gosling主导的团队创造了橡树语言,java的前身,1995年5月23号,Oak语言更名Java,并且提出那句注明的:“写一次,随处跑”的口号。1996年1月23日,JDK1.0发布。
当时正好赶上浏览器快速崛起,发展的浪潮,大家发现的java的一处编译到处使用的特性和浏览器很契合,同一个页面不可能每一个操作系统我都写一遍。用现在的话说的java的正好站在这个风口上。导致它飞速发展才有了今天的江湖地位。
一,JVM简介
JVM是Java的虚拟机(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真各种计算机功能来实现的的.java虚拟机包括一个字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
的的Java语言的一个非常重要的特点就是与平台的无关性。而使用的Java的虚拟机是实现这一特点的关键一般。的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入的的Java语言虚拟机后,爪哇的语言在不同平台上运行时不需要重新编译的的.java语言使用的的Java虚拟机屏蔽了与具体平台相关的信息,使得Java的的语言编译程序只需生成在爪哇的虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行的的.java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是爪哇的能够“一次编译,到处运行”的原因。
二,JVM的组成
我们先把JVM这个虚拟机画出来,如下图所示:
从这张图中我们可以看出,JVM是运行在操作系统之上的,它与硬件没有直接的交互,我们再来看JVM由哪些部分组成,如下图所示:
1,Class Loader类加载器
类加载器的作用是加类文件到内存,比如编写一个HelloWord.java程序,然后通过javac编译成class文件,那怎么才能加载到内存中被执行呢?Class Loader承担的就是这个责任,那不可能随便建立一个.class文件就能被加载的,Class Loader加载的class文件是有格式要求。
Class Loader只管加载,只要符合文件结构就加,至于说能不能运行,则不是它负责的,那是由Execution Engine负责的。
2,执行引擎执行引擎
执行引擎也叫做解释器(解释),负责解释命令,提交操作系统执行。
3,Native Interface本地接口
本地接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C / C ++程序,Java诞生的时候是C / C ++横行的时候,要想立足,必须有一个聪明的,睿智的调用C / C ++程序,于是在内部中专门开辟了一块区域处理标记为native代码,它的具体做法是Native Method Stack中登记native方法,在Execution Engine执行时加本机库。目前该方法使用的是越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机,或者Java系统管理生产设备,在企业级应用中已经比较少见,因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以使用Web Service等等,不多做介绍。
4,运行数据区运行数据区
运行数据区是整个JVM的重点。我们所有写的程序都被加到这里,之后才开始运行,Java生态系统如此的繁荣,得益于该区域的优良自治。
整个JVM框架由加载器加载文件,然后执行器在内存中处理数据,需要与异构系统交互是可以通过本地接口进行,瞧,一个完整的系统诞生了!
三,JVM的内存管理
所有的数据和程序都是在运行数据区存放,它包括以下几部分:
1,堆栈
栈也叫栈内存,是的Java程序的运行区,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束,该栈就在问题出来了:?栈中存的是那些数据呢又什么是格式呢?
栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧F1,并被压入到栈中,A方法又调用了乙方法,于是产生栈帧F2也被压入栈,执行完毕后,先弹出F2栈帧,再弹出F1栈帧,遵循“先进后出”原则。
那栈帧中到底存在着什么数据呢?栈帧中主要保存3类数据:本地变量(Local Variables),包括输入参数和输出参数以及方法内的变量;栈操作(操作数堆栈),记录出栈,入栈的操作;栈帧数据(Frame Data),包括类文件,方法等等。光说比较枯燥,我们画个图来理解一下Java栈,如下图所示: