1说一下 jvm 的主要组成部分?及其作用?
类加载器(ClassLoader):负责将字节码文件加载到内存中,并生成对应的类对象。
执行引擎(Execution Engine):负责执行字节码指令,常见的执行引擎有解释器和即时编译器。
运行时数据区(Runtime Data Area):用于存储程序运行时的数据和信息。
垃圾收集器(Garbage Collector):负责自动回收不再使用的对象内存空间。
运行时类库(Runtime Class Libraries):包含了 Java 标准库和其他系统库,提供了各种类和方法供程序使用。
2说一下 jvm 运行时数据区?
方法区(Method Area):用于存储类的结构信息、常量、静态变量等。
堆(Heap):用于存储对象实例,是JVM中最大的一块内存区域。
栈(Stack):每个线程在运行时都会创建一个栈帧(Stack Frame),用于存储局部变量、操作数栈、方法出口等。
本地方法栈(Native Method Stack):用于存储本地方法(Native Method)的调用和执行过程。
程序计数器(Program Counter Register):用于记录当前线程执行的字节码指令地址。
3说一下堆栈的区别?
堆是用于存储对象实例的内存区域,由JVM在启动时创建。堆的大小可以通过参数进行调整,并且被所有线程共享。堆内存的分配和回收由垃圾收集器负责。
栈是每个线程独立拥有的内存区域,用于存储局部变量、方法调用和返回值等信息。栈的大小是固定的,由编译器或JVM设置决定。栈内存的分配和回收随着线程的创建和销毁而发生。
4队列和栈是什么?有什么区别?
队列是一种先进先出(FIFO)的数据结构,元素在队列尾部添加,在队列头部删除。
栈是一种后进先出(LIFO)的数据结构,元素在栈顶添加和删除。
主要区别在于元素的添加和删除顺序,队列是按照先进先出的顺序操作,而栈是按照后进先出的顺序操作。
5什么是双亲委派模型?
是Java类加载机制中的一种策略,用于保护核心库的安全性和稳定性。该模型规定,除了一些特殊的类加载器外,类加载器在加载类时会先委派给父类加载器加载,只有当父类加载器无法加载时,才由子类加载器自行加载。这种层级关系可以避免类被重复加载,确保类的唯一性和安全性。
6说一下类加载的执行过程?
加载(Loading):根据类的全限定名查找字节码文件,并将其加载到内存中。
验证(Verification):对加载的字节码文件进行验证,确保符合JVM规范。
准备(Preparation):为类的静态变量分配内存,并设置默认初始值。
解析(Resolution):将常量池中的符号引用解析为直接引用。
初始化(Initialization):为类的静态变量赋予正确的初始值,并执行静态代码块。
使用(Using):调用类的方法,创建对象等。
卸载(Unloading):当类不再使用时,将其从内存中卸载。
7怎么判断对象是否可以被回收?
引用计数法(Reference Counting):记录对象被引用的次数,当引用数为0时表示对象不再被使用。
可达性分析法(Reachability Analysis):从一组根对象开始,通过引用链追踪对象的可达性,如果对象不可达则视为垃圾对象。
垃圾收集器特定的算法和策略:如标记-清除、复制算法等。
8java 中都有哪些引用类型?
强引用(Strong Reference):最常见的引用类型,通过关键字new创建的对象默认是强引用,只要强引用存在,垃圾收集器就不会回收该对象。
软引用(Soft Reference):用于描述还有用但非必需的对象,内存空间足够时不会被回收,当内存不足时,垃圾收集器会回收软引用对象。
弱引用(Weak Reference):用于描述非必需的对象,只能存活到下一次垃圾收集发生之前,无论内存是否充足,垃圾收集器都会回收弱引用对象。
虚引用(Phantom Reference):用于描述对象被回收的状态,无法通过虚引用获取对象的实例,主要用于跟踪垃圾回收过程。
9说一下 jvm 有哪些垃圾回收算法?
标记-清除算法(Mark and Sweep):标记阶段遍历并标记所有存活对象,清除阶段回收未被标记的对象。
复制算法(Copying):将内存分为两个相等的区域,每次只使用其中一个区域,当该区域用尽时,将存活的对象复制到另一个区域,然后清除当前区域中的所有对象。
标记-整理算法(Mark and Compact):标记阶段遍历并标记所有存活对象,整理阶段将存活对象移动到内存的一端,然后清理边界外的内存。
分代收集算法(Generational Collection):根据对象的生命周期将堆内存划分为不同的代,通过不同的垃圾回收算法对不同代进行回收。一般将堆分为新生代和老年代。
10说一下 jvm 有哪些垃圾回收器?
Serial收集器:单线程执行,采用复制算法,适用于小型应用。
Parallel收集器:多线程执行,并行地进行垃圾回收,适用于多核服务器。
CMS收集器(Concurrent Mark and Sweep):以最短停顿时间为目标,使用标记-清除算法,适用于对延迟要求较高的应用。
G1收集器(Garbage-First):将堆内存分割成多个区域,通过多线程并发执行,适用于大堆内存和低延迟要求的应用。
11详细介绍一下 CMS 垃圾回收器?
垃圾回收器是一种以最短停顿时间为目标的收集器。它采用标记-清除算法,在垃圾回收过程中,标记阶段和清除阶段可以与应用程序的执行并发进行。CMS收集器主要包含以下几个阶段:
初始标记(Initial Mark):暂停所有的应用线程,标记GC Roots能直接关联到的对象,并记录下需要在并发标记阶段继续标记的对象。
并发标记(Concurrent Mark):与应用程序并发执行,标记所有从GC Roots可达的对象。
重新标记(Remark):暂停所有的应用线程,修正在并发标记期间因应用程序继续运行而发生变化的对象标记状态。
并发清除(Concurrent Sweep):与应用程序并发执行,清除所有标记为垃圾对象的内存空间。
并发重置(Concurrent Reset):重置CMS收集器的数据结构,为下一次垃圾回收做准备。
12新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
新生代垃圾回收器主要负责回收新生代的对象,常见的有Serial、ParNew和G1等。新生代采用复制算法,将内存分为Eden空间和两个Survivor空间,通过对象的复制来进行垃圾回收。
老年代垃圾回收器主要负责回收老年代的对象,常见的有Serial Old、Parallel Old和CMS等。老年代通常使用标记-清除或标记-整理算法,根据应用程序的需求选择最合适的回收算法。
13简述分代垃圾回收器是怎么工作的?
分代垃圾回收器的工作原理是基于对象的生命周期 将堆内存划分为不同的代(一般是新生代和老年代),并使用不同的垃圾回收算法对不同代进行回收。具体工作流程如下:
新生代中的对象多为朝生夕灭,采用复制算法进行垃圾回收,将存活的对象复制到Survivor区域或老年代。
新生代中的Eden区域满时,触发Minor GC,将存活的对象复制到Survivor区域。
多次Minor GC后,Survivor区域仍然存活的对象会被晋升到老年代。
老年代中的对象多为长生命周期对象,采用标记-清除或标记-整理算法进行垃圾回收。
当老年代空间不足时,触发Major GC(Full GC),对整个堆内存进行回收。
14说一下 jvm 调优的工具?
jps:查看当前正在运行的Java进程。
jstat:监控JVM的各种运行数据,如堆内存使用情况、GC统计等。
jmap:生成堆内存的快照文件,用于分析内存使用情况。
jstack:生成Java线程的堆栈信息,用于分析死锁和线程等待问题。
jconsole:一个图形化的监控工具,用于实时查看JVM的运行状态。
VisualVM:功能强大的图形化监控和分析工具,提供丰富的插件支持。
15常用的 jvm 调优的参数都有哪些?
-Xms:指定JVM的初始堆大小。
-Xmx:指定J