1.什么是JVM?
JVM是Java虚拟机(Java Virtual Machine)的缩写,是Java程序运行的核心组件。JVM是一个虚拟的计算机,它提供了一个独立的运行环境,可以在不同的操作系统上运行Java程序。
2.如何判断可回收垃圾对象
Java中的垃圾回收器使用的是"可达性分析"算法来判断对象的可达性。这个算法从一组称为"GC Roots"的对象作为起点,通过引用链追踪所有的引用对象,如果一个对象无法通过任何引用链与GC Roots相连,那么这个对象就是不可达的,即可被判断为垃圾对象。
在Java中,GC Roots是指一组对象,它们被认为是活动的,即不会被垃圾回收器回收的对象。GC Roots包括以下几种实例:
- 虚拟机栈(Java虚拟机栈中的局部变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(Java Native Interface)引用的对象
- 活动的线程
3.常见的垃圾算法
1.标记-清除算法(Mark and Sweep)
这是最基本的垃圾回收算法之一。在这个算法中,JVM会首先标记所有活动对象,然后清除所有未标记的对象,释放它们所占用的内存空间。缺点:碎片化。
2.复制算法(Copying)
这个算法将内存空间划分为两个相等的区域,当一个区域的内存用尽时,JVM会将存活的对象复制到另一个区域,然后清除原区域中的所有对象。这个算法的优点是简单高效,但缺点是需要额外的内存空间。
3.标记-整理算法(Mark and Compact)
这个算法结合了标记-清除和复制算法的优点,它首先标记所有活动对象,然后将它们向一端移动,清除另一端的所有对象,从而整理内存空间。缺点:效率比copy略低。
4.分代收集算法(Generational Garbage Collection)
是一种用于垃圾回收的策略,它根据对象的存活周期将堆内存分为新生代和老年代,并针对不同代的对象采用不同的垃圾回收算法和策略。
新生代:包括Eden空间和两个Survivor空间(From和To)
老年代:包含长期存活的对象
分代收集算法通常包括以下两个主要的垃圾回收策略:
- 新生代垃圾回收:由于大部分对象的生命周期很短,因此新生代的垃圾回收频率较高。通常采用复制算法(Copying)来进行垃圾回收,即将新生代的Eden空间和Survivor空间之间进行对象复制,清除不再使用的对象。这样可以有效地清理短期存活的对象,减少垃圾回收的开销。
- 老年代垃圾回收:由于老年代包含长期存活的对象,因此老年代的垃圾回收频率较低。通常采用标记-清除(Mark-Sweep)或标记-整理(Mark-Compact)算法来进行垃圾回收,以清理老年代中的不再使用的对象,并整理内存空间,减少内存碎片化。
4.在分代算法的基础之上,有哪些垃圾回收器
(1)Serial
Serial收集器采用复制算法(Copying)来进行新生代的垃圾回收。在进行垃圾回收时,Serial收集器会将新生代的Eden区和两个Survivor区之间进行对象复制,清除不再使用的对象。由于它是单线程的,因此在进行垃圾回收时会暂停应用程序的运行,这种方式被称为"Stop-The-World"。
(2)ParNew
ParNew收集器是一种专门针对新生代的垃圾回收进行了优化的并行垃圾回收器,适用于需要高吞吐量和对响应速度要求较高的应用场景。
(3)Parallel Scavenge
Parallel Scavenge收集器的设计目标是在多核CPU环境下提供高吞吐量的垃圾回收能力,即在尽量减少垃圾回收暂停时间的同时,尽可能多地利用CPU资源来进行垃圾回收。它采用复制算法(Copying)来进行新生代的垃圾回收,同样会将新生代的Eden区和Survivor区之间进行对象复制,清除不再使用的对象。
(4)CMS
CMS收集器的垃圾回收过程分为两个阶段:标记阶段和清除阶段。在标记阶段,CMS收集器会通过多线程并发地标记出所有需要回收的对象;在清除阶段,CMS收集器会通过多线程并发地清除标记出来的垃圾对象。优点:减少垃圾回收暂停时间,提高应用程序的响应速度。
(5)Serial Old
Serial Old收集器是一种专门针对老年代的垃圾回收进行了优化的串行垃圾回收器,适用于对吞吐量要求不是很高,但对内存占用和延迟要求较低的应用场景。
(6)Parallel Old
Parallel Old收集器用于老年代的垃圾回收,采用多线程并行的方式进行垃圾回收操作,适用于对吞吐量要求较高的应用。