Java本身是一种面向对象的语言,最显著的特性有两个:一是所谓的“书写一次,到处运行”(Write once, run anywhere),能够非常容易地获得跨平台能力。另外就是"垃圾收集"(GC,Garbage Collection),Java通过垃圾收集器回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
Java特性:
面向对象(封装,继承,多态)
平台无关性(JVM运行.class文件)
语言(泛型,Lambda)
类库(集合,并发,网络,IO/NIO)
JRE(Java运行环境,JVM,类库)
JDK(Java开发工具,包括JRE,javac,诊断工具)
JRE为java提供了必要的运行时环境,JDK为java提供了必要的开发环境!
Java是解释执行吗?
不完全正确!
1、Java源代码经过Javac编译成.class文件(字节码)
2、.class文件经JVM解析或编译运行。(将字节码转换成最终的机器码)
(1)解析:.class文件经过JVM内嵌的解析器解析执行。
(2)编译:存在JIT编译器(Just In Time Compile 即时编译器,也就是通常所说的动态编译器)把经常运行的代码作为"热点代码"编译成与本地平台相关的机器码,并进行各种层次的优化。这种情况下部分热点代码就属于编译执行,而不是解释执行。(运行时编译)
-
疑问:什么是热点代码呢?换句话说,就是一段时间内执行比较频繁的代码。
-
那怎么统计呢?基于程序计数器的热点探测,为每个方法建立计数器,当访问次数达到一点阈值时就认为它是热点方法
-
缺点:编译机器码占用内存,收集探测热点影响程序运行等
-
JIT编译速度及编译结果的优劣,是衡量JVM性能的重要指标,对程序的性能调优集中在这个阶段
3、AOT编译器: Java 9的新特性,提供在运行前,直接将所有代码编译成机器码执行,是静态的,避免了JIT预热等各方面的开销。
4、jit是运行时时才做的,需要预热才知道哪些是热点;aot是编译期,静态的,直接编成类似类库的东西。
众所周知,我们通常把Java分为编译期和运行时。这里说的Java的编译和C/C++是有着不同的意义的,Javac的编译,编译Java源码生成".class"文件里面实际是字节码,而不是可以直接执行的机器码。Java通过字节码和Java虚拟机这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现"一次编译,到处执行"的基础。
严格的讲,跨平台的语言不止Java一种,但Java是较为成熟的一种。“一次编译,到处运行”这种效果跟编译器有关。编程语言的处理需要编译器和解释器。Java虚拟机和DOS类似,相当于一个供程序运行的平台。
程序从源代码到运行的三个阶段:编码——编译——运行——调试。Java在编译阶段则体现了跨平台的特点。编译过程大概是这样的:首先是将Java源代码转化成.CLASS文件字节码,这是第一次编译。.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的,即Java的第二次编译。
“到处运行”的关键和前提就是JVM。因为在第二次编译中JVM起着关键作用。在可以运行Java虚拟机的地方都内含着一个JVM操作系统。从而使JAVA提供了各种不同平台上的虚拟机制,因此实现了“到处运行”的效果。需要强调的一点是,java并不是编译机制,而是解释机制。Java字节码的设计充分考虑了JIT这一即时编译方式,可以将字节码直接转化成高性能的本地机器码,这同样是虚拟机的一个构成部分。
解释执行和编译执行
- 解释执行:所谓执行相当于在我们的代码和电脑之间有一个翻译官,每当我们输入一个指令,那么这个翻译官就会及时的翻译给机器;
- 编译执行:编译执行就是通过编译器将我们输入的所有指令进行编译,然后一次的翻译给机器可以识别的机器码;
通过比较两种执行方式我们可以发现,解释执行对于程序员的要求可能低一点,但是执行效率比较低,相反编译执行对程序员你的要求高一点,但是它的执行效率也比较高一点。
编译程序是整体编译完了,再一次性执行。 而解释程序是一边解释,一边执行。