java核心技术36讲-第1讲-谈谈你对Java平台的理解?

java基础第一讲,谈谈你对Java平台的理解?

总结一下看这篇文章时,不懂的一些点。

1. 关于对Just In Time编译器。

在主流商用JVM(HotSpot、J9)中,Java程序一开始是通过解释器(Interpreter)进行解释执行的。当JVM发现某个方法或代码块运行特别频繁时,就会把这些代码认定为“热点代码(Hot Spot Code)”,然后JVM会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为:即时编译器(Just In Time Compiler,JIT)。

2. java程序执行步骤

首先javac编译器将源代码编译成字节码(.class文件)。
然后jvm类加载器(class-loader)加载字节码文件,然后通过解释器逐行解释执行(读取一条指令,解释一条指令,执行一条指令),这种方式的执行速度相对会比较慢。有些方法和代码块是高频率调用的,也就是所谓的热点代码,所以引进jit技术,将这类字节码(热点代码)直接编译成本地机器码,保存在codecache中。这样类似于缓存技术,运行时再遇到这类代码直接可以执行,而不是先解释后执行。

3. jdk中工具

1. javac
2. jconsole 
    - 监控诊断工具
    - JConsole可视化工具介绍: https://blog.csdn.net/qq_31156277/article/details/80035430
    - 一种基于JMX的可视化监视,管理 工具。
3. jmap 
    - 监控诊断工具
    - 命令jmap是一个多功能的命令。它可以生成java程序的dump文件,也可以查看堆内对象示例的统计信息、查看ClassLoader的信息以及finalizer队列。
4. jstack
    - jstack命令解析: https://www.jianshu.com/p/8d5782bc596e

4. java是解释执行的吗

这句话说得不是很正确,我们开发的源代码,首先通过Javac将源代码编译成字节码文件,然后在运行时通过JVM内嵌的解释器将字节码转换为最终的机器码。但是常见的JVM都提供了即时编译器(JIT),编译器能够在运行时将热点代码编译成机器码,这种情况下部分代码就属于编译执行,而不是解释执行。

5. java中编译器分类

其实编译器可以分为:前端编译器、JIT 编译器和AOT编译器。

前端编译器就是平时使用的javac,这种称为前端编译器,它负责编译成.class文件。

当源代码转化为字节码之后,其实要运行程序,有两种选择。一种是使用 Java 解释器解释执行字节码,另一种则是使用 JIT 编译器将字节码转化为本地机器代码(JIT也分为两种,C1和C2)。这两种方式的区别在于,前者启动速度快但运行速度慢,而后者启动速度慢但运行速度快。

至于为什么会这样,其原因很简单。因为解释器不需要像 JIT 编译器一样,将所有字节码都转化为机器码,自然就少去了优化的时间。而当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。

所以在实际情况中,为了运行速度以及效率,我们通常采用两者相结合的方式进行 Java 代码的编译执行。我们也可以自己选择三种模式混合模式(Mixed Mode),解释模式(Interpreted Mode),编译模式(Compiled Mode)。

AOT 编译器的基本思想是:在程序执行前生成 Java 方法的本地代码,以便在程序运行时直接使用本地代码。

AOT编译器,可以通过jaotc工具生成类似于类库的文件,该目标对象是HelloWorld.class,所以AOT是将.class文件生成本地机器码,而非.java文件。

6. java内存结构 & java内存模型 & java对象模型

jvm 运行时内存结构: java虚拟机运行时数据区域有关.
java 内存模型 :java并发编程有关,共享内存的可见性、原子性、有序性。
java 对象模型 :java对象的存储结构,不同对象存储在不同数据区,方法区、堆、栈。

7. JDK和JRE区别

JRE包括jvm虚拟机,java类库,支持模块,是java程序运行的标准环境。
JDK是JRE的超集,多了编译工具,安全机制,诊断检测工具。

8. jre将退出舞台,此话怎讲?

有了jigsaw,利用jlink可以定制最合适的runtime,plugin之类也逐渐退役了,jre的存在需求在降低。

9. C语言不能跨平台原因

相比C语言,C语言会直接调用os的api,不同的os的api不一样,C语言需要修改源代码。

java平台能跨语言的原因是加入了每个平台都有自己定制的jvm虚拟机,其他语言也可以实现类似的模式,jvm能够解释的是字节码。将字节码转化为更高性能的机器码是编译,即JIT的编译器,属于动态编译器的一种,运行中再将字节码转化为机器码

10. 倘若jit只保留编译器存在哪些问题

  1. jvm启动较慢,要将所有的字节码得全部编译需要一定的时间,难以满足需要应用程序迅速响应的场景;

  2. 一次性的编译成机器码导致CPU的一些优化特性如分支预测难以发挥,因为其需要程序运行后统计其特性才能对其预测,其性能可能受到影响。所以在实际中jit需要解释器的存在。

所以jvm默认以分层的模式运行.可以通过-Xint,-Xcompl,-Xmixed选择需要的模式。(这也是为什么JRE会有server,client两种模式,server启动慢,但执行效率高,client响应较快)。

11. 编译执行与解释执行

解释执行是将编译好的字节码一行一行地翻译为机器码执行;

编译执行是以方法为单位,将字节码一次性翻译为机器码后执行。

例如:n = n +1; 对于这句代码解释执行就是当虚拟机读到这行代码的时候才把它加载到内存去执行。编译执行就是提前把这些代码编译到内存里面了,然后直接调用。解释执行与编译执行的优缺点:解释执行可以更好的和计算机进行交流,但是执行效率特别低。比如你同一句代码,可能要执行100万次,结果你就加载了100万次。编译执行好处就是执行效率高,缺点是有些代码或许在整个Application只执行1次,但是你也加载到内存里面了,那就是浪费内存资源。JIT就做到了大部分代码编译,冷代码不编译的特点。

Last modification:November 16th, 2020 at 08:31 pm
有钱的捧个钱场,没带钱的捧个人场。

Leave a Comment