面经集合


JVM

[TOC]

6.  JVM

6.1. 

6.1.1.  JDK、JRE、JVM

1.  JDK:Java Development Kit = JRE + Java开发工具,可以创建和编译Java程序

2.  JRE :Java Runtime Environment = JVM + JAVA核心类库,是一个包含了运行已编译的Java程序所需要的全部内容的集合

3.  JVM:Java Virtual Machine = 类加载器+执行引擎+运行时数据区+本地接口

6.1.2.  JVM只有一种吗?

JVM并不是只有一种,任何组织、个人都可以在符合JVM规范的基础上开发属于自己的JVM,目前的JVM有HotSpot VM、J9 VM、Zing VM、JRockit VM等

6.1.3.  JVM /  Java虚拟机

Java虚拟机在程序开始执行的时候就开始实例化了,多个程序同时执行会实例化多个虚拟机,不同的虚拟机之间数据不能共享,程序退出或者关闭的时候,虚拟机会被销毁。

6.1.4.  程序变量运算原理

当程序中使用到某个变量的值的时候,例如变量参与算术运算、以变量的值进行赋值等,会首先把变量的值存入操作数栈,程序中用到变量的值时,计算机会从操作数栈中取值进行运算

6.1.5.  JVM内存结构

JVM内存结构=类加载器 + 执行引擎 + 运行时数据区(堆, 虚拟机栈, 本地方法栈, 方法区, PC寄存器)

6.1.6.  JVM运行时数据区有哪些

6.1.7.  什么是堆内存

6.1.8.  内存溢出、内存泄漏

6.1.9.  JVM类加载过程

6.1.10.  垃圾回收器

6.1.11.  串行垃圾收集

6.1.12.  并行垃圾收集

6.1.13.  并发垃圾收集

6.1.14.  GC停顿、STW停顿

6.1.15.  JVM调优

6.1.16.  Java代码执行原理

Java源代码 .java 经过编译器编译成字节码 .class 经过解释器解释成对应平台的机器码

6.1.17.  什么是字节码

由Java源码经过编译器编译得到的.class文件

6.1.18.  字节码的优点

Java语言通过字节码的方式,在一定程度上解决了其他解释型语言执行效率低的问题,同时保留了解释型语言可移植的特点。

因为Java虚拟机的存在,Java程序编译为字节码后可以直接在其他类型的机器上运行,不需要重新编译。

6.1.19.  解释型语言

解释型语言的程序不需要编译,在运行时会逐行翻译成机器语言,每次运行都需要翻译一次,因此执行效率较低

6.1.20.  编译型语言

编译型语言的程序需要先把程序编译成机器码,之后再执行,再次运行时不需要重新编译,直接使用编译好的结果即可,因此执行效率较高,但是依赖编译器,所以跨平台性差一些。

6.1.21.  Java能够跨平台的原因

Java通过对应平台的JVM实现一份代码在不同的机器上运行

6.1.22.  Java是编译与解释并存的语言

从字节码到机器码,Java虚拟机的类加载器会首先加载Java字节码文件,然后通过解释器逐行解释执行,但是这样会导致部分热点代码(就是那些多次被调用的代码)会被多次解释,执行速度会相对较慢。

因此引入了JIT just-in-time 编译器 / 即时编译器,它可以在执行时搜集分析信息,通过它编译热点代码,然后把编译后的机器码保存下来,下次可以直接使用

6.1.23.  HotSpot采用的是惰性评估的方法

根据二八定律,占用大部分资源的仅仅是那一小部分热点代码,这也就是JIT需要编译的部分,引入JIT后,JVM每次执行的时候都会搜集分析信息并作出优化,因此执行次数越多,运行速度就越快。

6.1.24.  AOT ahead of time

JDK9采用了新的编译模式AOT ahead of time,运行时直接将字节码翻译成机器码,并将其缓存到共享数据高速缓存中,以便后续JVM执行该方法时直接从共享数据高速缓存中载入和使用,这样就减少了JIT预热的开销。

6.1.25.  为什么不全部采用AOT

虽然AOT可以提前编译节省启动时间,但是全部采用提前编译的方式,就不能做到动态编译了

6.1.26.  JIT执行流程

JVM类加载器加载字节码,进行解释执行,到方法调用的时候,优先判断是否经过JIT编译过,

● 是就直接读取缓存中编译好的机器码来执行,

● 否就解释执行,并调用次数统计,如果超过某个阈值,就会触发JIT编译并将其编译结果存入缓存中

页面列表

ITEM_HTML