面试点总结:
1、为什么Java被称为跨平台的语言,JVM被称为跨语言的平台?
答:java被称为跨平台的语言主要是因为其JVM,不同的操作系统之上都有对应的JVM实现,Java程序只需要编译成class文件,就可以运行在不同的JVM之上。而JVM只关心字节码文件,并不关心它是由什么语言编写的,只要编译成的字节码文件符合JVM规范(比如开头由CafeBabe标识),那么它就可以在JVM上运行。
2、画出JVM的内存结构:
3、方法区用于存储那些结构?其具体实现是什么
答:方法区只是hotspot虚拟机提出的一个概念上的结构,其具体实现在1.7中是永久代;1.8之后是元空间;方法区包含类元信息、方法元信息、1.7之前还包含运行时常量池(运行时常量池逻辑包含字符串常量池),1.7时字符串常量池移到了堆中,1.8之后运行时常量池也移到了堆中。运行时常量池中包含常量、静态变量。此外还包含JIT编译的代码缓存。
4、说说java代码的执行流程:
答:首先java源代码被编译器编译成class文件,然后类加载子系统通过反射找到该class文件并且以字节流的方式将其加载到JVM中的运行时数据区,然后再由执行引擎进行解释执行(这其中包含热点代码检测,会将热点代码经过即时编译器编译进行缓存),最后再将得到的机器码交由操作系统之上的cpu进行真正的执行。
5、JVM是基于什么架构实现的,有什么优缺点?
答:JVM是基于栈的指令集架构模型,还有一种是基于寄存器的指令集架构模型。基于栈的指令集架构其采用零地址指令,指令集较小,编译器容易实现,并且不依赖硬件便于移植;但是实现操作时的指令较多,相较于寄存器指令架构执行效率较差。基于寄存器的指令集架构,可以采用一、二、三地址指令,执行操作的指令较少,执行效率高。但指令集较大且依赖硬件,不便于移植。
扩展:指令中的地址码字段用来指出操作数的地址。根据一条指令中所含操作数地址的数量。可分为三地址指令、双地址指令、单地址指令和零地址指令。零地址指令只有操作码,没有操作数
6、JVM的生命周期?
答:分为启动、执行和销毁三个部分。JVM生命周期是和程序的执行相关的,当一个程序启动JVM的一个Runtime实例就会被创建,java程序的执行实际上是java虚拟机进程在执行,当程序执行结束JVM也会随之销毁。(关于JVM启动可以参考这个)
JVM概述
1、JVM简介
与java称为跨平台的语言类似,JVM可以称为跨语言的平台;JVM只关心字节码文件,只要编译出的字节码文件符合JVM规范(如:文件的开头有cafebabe魔数标识)就可以在JVM上运行。
因此JVM的一个发展趋势是多语言混合编程,运用特定领域的语言来解决特定领域的问题,最后统一编译成字节码文件运行在JVM上。
补充:ZGC是JDK11版本发布的具有革命意义的垃圾回收器,用于代替现在使用的G1垃圾回收器(经测试ZGC已经在各方面超越了G1垃圾回收器)
JVM(Hotspot)体系结构:
1.方法区和堆区是所有线程共享的内存区域;而java栈、本地方法栈和程序员计数器是运行时线程私有的内存区域。
2.Java栈又叫做jvm虚拟机栈
3.方法区(永久代)在jdk8中又叫做元空间Metaspace
- 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT编译器,英文写作Just-In-Time Compiler)编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。
- 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
- 在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
- 在JDK1.8之后JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。同时在 jdk 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域
4.java代码执行流程:
java程序–>(编译javac)–>字节码文件.class–>类装载子系统化身为反射类Class—>运行时数据区—>(解释执行)–>操作系统(Win,Linux,Mac JVM)
阿里手册中的图:
2、JVM的位置
JVM是运行在操作系统之上的,它与硬件没有进行直接的交互;这也是JVM能够实现跨平台特性的重要原因。
对于java语言来说JDK=JRE+工具类(JDK构成图),JRE=JVM+java核心类库;如下图所示:
java代码的执行流程:
java源码经过java编译器编译成字节码文件,再通过类加载器加载到JVM中,在虚拟机中经过一系列的字节码校验、解释执行(解释器)、编译执行(即时编译器)最后后运行在操作系统之上。
补充:字节码文件并不是机器指令,需要通过执行引擎来执行得到的字节码文件。
3、JVM的架构模型
JVM是基于栈的指令集架构模型,还有一种是基于寄存器的指令集架构模型。
两种架构的区别如下:
基于栈的指令集架构:
优点:主要使用零地址指令,指令集更小,编译器更易实现;不依赖于硬件,可移植性更好便于实现跨平台。
缺点:执行操作的指令更多,执行的性能比寄存器差
基于寄存器的指令集架构:
优点:执行操作的指令更好,性能优秀执行更高效。
缺点:主要采用一地址、二地址、三地址指令,指令集较大,完全依赖硬件,可移植性差。
一些简单的操作:(到达class文件的根目录下执行)
//反编译
javap -v xxx.class
//打印程序执行的进程
jps
4JVM的生命周期
1、虚拟机的启动
java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类来完成的,这个类由虚拟机的具体实现指定。
2、虚拟机的执行
java虚拟机的的目的是为了执行java程序,它在程序开始执行时才开始运行,程序结束是它就会停止。执行java程序时真正在执行的是一个叫做java虚拟机的进程。
3、虚拟机的退出
虚拟机的退出可能是多种情况造成的,如:程序正常执行结束、程序执行过程中遇到了异常或错误而异常终止或者是操作系统出现问题而导致java虚拟机进程终止等。具体如下:
- 程序正常执行结束
- 程序异常或错误而异常终止
- 操作系统错误导致终止
- 某线程调用Runtime类或System类的exit方法,或Runtime类的halt方法,并且java安全管理器也允许这次exit或halt操作
- 除此之外,JNI规范描述了用JNI Invocation API来加载或卸载Java虚拟机时,Java虚拟机的退出情况
5、JVM的特点
1、一次编译,到处运行(跨平台性)
2、自动的内存管理策略
3、自动的垃圾回收机制
扩展知识
世界上第一款商用的虚拟机:Sun classic VM,只提供了解释器(使用即时编译器需要外挂,且不能和解释器配合工作,二者只能选择其一。)
Exact VM:具备了现代高性能虚拟机的特性,具有热点探测;解释器和即时编译器混合工作模式。
三大主流商用的虚拟机:
HotSpot虚拟机:编译器和解释器协同工作。从JDK1.3使用到现在;(只有HotSpot有方法区的概念)
JRocket:专注于服务器端的应用;只使用即时编译器,不使用解释器(是世界上执行速度最快的虚拟机)
J9:IBM公司的虚拟机。