Java后台开发面试实战(十三):初识JVM
感谢牛客网网友提供的面试经验!
图片来源:https://blog.****.net/gushidefengzheng/article/details/78653921
1. 说一下 JVM 的主要组成部分?
- 类加载器(ClassLoader)
- 运行时数据区(Runtime Data Area)
- 执行引擎(Execution Engine)
- 本地库接口(Native Interface)
- 各组件的作用?
首先通过类加载器会把 Java 代码转换成字节码,运行时数据区再把字节码加载到内存中,执行引擎负责将字节码翻译成底层系统指令,交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口来实现整个程序的功能。
- Java中的类加载机制有了解吗?
Java中的类加载机制指虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换、解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型。
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用、卸载七个阶段。类加载机制的保持则包括前面五个阶段。
2. 谈谈对运行时数据区的理解?
VM中的内存主要划分为5个区域,即方法区,堆内存,虚拟机栈,本地方法栈以及程序计数器。
- 方法区:它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等(存储的数据一般持久性比较强)数据。
- 堆内存:在虚拟机启动时创建,存放对象实例。Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC”堆(Garbage Collected Heap)。从内存回收的角度看,由于现在收集器基本都采用分代收集算法,所以 Java 堆中还可以细分为:新生代和老年代。
- 虚拟机栈:为虚拟机执行Java方法(也就是字节码)服务。
- 本地方法栈:为虚拟机使用到的 Native(调用非java代码的接口)方法服务。
- 程序计数器:是当前线程所执行的字节码的行号指示器。
- 哪些属于线程独占,哪些属于线程共享?
线程共享:方法区,堆内存
线程独占:程序计数器,虚拟机栈以及本地方法栈
- 解释下运行时常量池?
运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有一些信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
4. 堆和栈的区别是什么?
从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。
5. 谈谈对内存泄漏的理解?
在 Java 中,内存泄漏就是存在一些不会再被使用确没有被回收的对象,这些对象有下面两个特点:
- 这些对象是可达的,即在有向图中,存在通路可以与其相连;
- 这些对象是无用的,即程序以后不会再使用这些对象。
如果对象满足这两个条件,这些对象就可以判定为 Java 中的内存泄漏,这些对象不会被 GC 所回收,然而它却占用内存。