【面试:JVM】

来自Wikioe
跳到导航 跳到搜索


说说Java虚拟机的生命周期及体系结构?

参见:Java虚拟机生命周期和体系结构

Java 是如何实现跨平台的?

注意:跨平台的是 Java 程序,而不是 JVM。

JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的 JVM。

所谓“跨平台”,即实现“一次编译,到处运行”:

  1. 我们编写的 Java 源码,编译后会生成一种 .class 文件,称为字节码文件;
  2. Java 虚拟机(JVM)负责将字节码文件翻译成特定平台下的机器码然后运行。

也就是说,只要在不同平台上安装对应的 JVM,就可以运行字节码文件,运行我们编写的 Java 程序,这个过程,我们编写的 Java 程序没有做任何改变,仅仅是通过 JVM 这一“中间层”,就能在不同平台上运行(不同平台使用不同的 JVM 实现),从而实现“跨平台”。

什么是 JVM ?

JVM,即 Java 虚拟机(“Java Virtual Machine”)。它通过模拟一个计算机来达到一个计算机所具有的的计算功能。JVM 能够跨计算机体系结构来执行 Java 字节码,主要是由于 JVM 屏蔽了与各个计算机平台相关的软件或者硬件之间的差异,使得与平台相关的耦合统一由 JVM 提供者来实现。

JVM 由哪些部分组成?

JVM 的结构基本上由 4 部分组成:

  1. 类加载器,在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中。
  2. 执行引擎,执行引擎的任务是负责执行 class 文件中包含的字节码指令,相当于实际机器上的 CPU。
  3. 内存区,将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者 PC 指针的记录器等。
  4. 本地方法调用,调用 C 或 C++ 实现的本地方法的代码返回结果。

说一说类加载器?

Java 虚拟机是如何判定两个 Java 类是相同的?

Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。

只有两者都相同的情况,才认为两个类是相同的。

即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。

比如一个 Java 类 com.example.Sample,编译之后生成了字节代码文件 Sample.class。两个不同的类加载器 ClassLoaderA 和 ClassLoaderB 分别读取了这个 Sample.class文件,并定义出两个 java.lang.Class 类的实例来表示这个类:
  • 这两个实例是不相同的;
  • 对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常 ClassCastException。

类似-Xms、-Xmn这些参数的含义?

堆内存分配:

  1. -Xms:初始分配的内存,默认是物理内存的1/64
  2. -Xmx:最大分配的内存,默认是物理内存的1/4
    • 默认空余堆内存小于 40% 时,JVM就会增大堆直到 -Xmx 的最大限制;空余堆内存大于 70% 时,JVM会减少堆直到 -Xms 的最小限制。
    • 因此服务器一般设置 -Xms、-Xmx 相等以避免在每次 GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

非堆内存分配:

  1. -XX:PermSize:设置非堆内存初始值,默认是物理内存的1/64;
  2. -XX:MaxPermSize:设置最大非堆内存的大小,默认是物理内存的1/4。
  3. -Xmn2G:设置年轻代大小为2G。
  4. -XX:SurvivorRatio:设置年轻代中 Eden 区与 Survivor 区的比值。