Java两种核心机制
- Java虚拟机(Java Virtual Machine),简称JVM
- 垃圾回收机制(Garbage Collection),简称GC
Java语言特点
- 两个基本概念:类、对象
- 三大特性:封装、继承、多态
- 吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制
- 跨平台性:通过Java语言编写的应用程序在不同的系统平台上都可以运行。“Write once , Run Anywhere”,一次编写,处处运行
- 原理:只要在需要运行 java 应用程序的操作系统上,先安装一个Java虚拟机 (JVM Java Virtual Machine) 即可。由JVM来负责Java程序在该系统中的运行。
1、Java语言的运行机制—JVM
首先,我们介绍一下什么是计算机语言。对于计算机来说,真正能够直接执行的是所谓的"计算机指令"。这种计算机指令,一方面跟着操作系统有关,也就是说,Windows系统和Linux系统下的指令不同。另一方面说,也跟计算机的硬件有关系,不同的CPU具有不同的指令集。
直接操作计算机指令,使用的是计算机语言以及汇编语言。
汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。
计算机指令:不经翻译即可为机器直接理解和接受的程序语言或指令代码
然而,对于程序员来说,直接使用汇编语言来编写程序进行开发是非常慢的,为了能让程序开发的速度提升,设计出了计算机高级语言。
所谓的计算机高级语言,实际上指的是:人为规定的一些语法。然而在遵循这些语法的前提下,写出一个文本文件,之后利用某种方式,把文本文件转化为机器指令进行执行。我们现在所谓的编程,往往指的就是编写文本文件这个部分。这个文本文件一般我们称之为源文件
那么,如何把一个源文件转化成为机器指令进行执行呢?在现代计算机语言中,主要有两种方式:一种是编译型,一种是解释型。
什么叫编译型语言呢?指的是,通过一个编译器软件把源文件转化为可执行文件。可执行文件的内容就是一些机器指令,以及相关的一些数据。在Windows中,可执行文件往往以.exe作为后缀。在执行程序的时候,不需要源代码文件,只需要可执行文件即可。
示意如下:文本文件(源文件) ——> 编译器——> 可执行文件(运行可执行文件)——>机器指令
与编译型语言相对的是解释型语言。解释型语言需要一个解释器软件。这个软件会读取源文件,在读源文件的过程中,同时完成将源文件内容翻译成机器指令以及执行的过程。换句话说,解释器将读取源文件、翻译成机器指令、执行指令这三步同时完成。
示意如下:文本文件(源文件) ——>解释器——>直接翻译成机器指令
由此可知,编译型语言在将源文件编译成可执行文件之后,运行程序只需要可执行文件,不在需要重复编译源文件的过程。而解释型语言每次运行时必须重复翻译源文件,因此从运行效率上来说,解释型语言远远不如编译型语言。
当然,解释型语言也有自己的优势:跨平台型比较好。由于编译型语言运行时只需要可执行文件,而可执行文件又与平台紧密相连,这就意味着,对于不同的平台,必须要有不同的可执行文件。而相对于解释型语言而言,对于不同的平台,只需要有不同的解释器就可以了,源代码几乎不用进行修改。
而Java语言,则兼有编译型和解释型两种语言的特点:Java语言运行时,采用的是先编译、后解释的方式运行。
首先,Java源代码要以后缀为.java的源文件。然后,通过一个编译器,编译生成.class文件,这个文件被称之为"二进制字节码文件"。
而.class文件并不能够直接在机器上运行。执行.class文件需要一个解释器,这个解释器会把.class文件翻译成真正机器上的指令。也就是说,需要解释执行.class文件。
示意如下:.java源文件——>编译——>.class字节码文件——>解释执行——>真正的机器指令
字节码文件是平台中立的,也就是说,运行在不同平台上的.class文件内容相同,与所在的平台无关。
那么.class文件保存的是什么内容呢?这个文件保存的也是计算机指令。所不同的是,这些计算机指令不是真实计算机所拥有的指令,而是一些虚拟的指令。在解释执行.class文件指令时,为了能让这些虚拟的计算机指令能够转换成真正的计算机指令。我们需要一个Java虚拟机(Java Virtual Machine,简称JVM)。
JVM事实上是一个软件,这个软件为Java程序模拟出一个统一的运行环境。Java程序只需要适应这个虚拟的环境。而与底层真正的硬件环境以及操作系统环境无关。换句话说:JVM的作用在于,它屏蔽了不同操作系统之间的差异。
JVM接收.class文件中的虚拟指令,这些指令很类似于真正的汇编语言指令,但这些指令与底层的操作系统平台和硬件平台无关,完全是另外设计出的一套独立体系。而不同平台下的JVM,在执行时,会把.class文件中的虚拟机指令翻译成对应平台上真正的计算机指令。因此,上面的示意如下:
.java源文件——>编译——>.class文件(二进制字节码文件)——>在JVM中解释执行——>真正的机器指令
Java语言这种"先编译,后解释"的运行机制。使得其同时拥有了编译型语言的高效性和解释型语言的跨平台性,Sun公司给出了最好的解释"Write once, run anywhere"。
2、Java语言的运行机制—GC
与C/C++相比,java语言不需要程序员直接控制内存回收,java程序的内存分配和回收都是由JRE在后台自动进行,JRE会负责回收那些不再使用的内存,这种机制被称为垃圾回收机制,即GC。
垃圾回收机制的意义:java 语言中一个显著的特点就是引入了java回收机制,是c++程序员最头疼的内存管理的问题迎刃而解,它使得java程序员在编写程序的时候不在考虑内存管理。由于有个垃圾回收机制,java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。
说到这,不得不提起内存泄漏(memory leak)和内存溢出(out of memory)
内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
内存溢出:指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出。