JVM中的垃圾收集器有哪些,它们的工作原理是什么?
JVM中的垃圾收集器主要包括以下几种:
1、 Serial收集器:它是一个单线程收集器,工作时会暂停所有其他工作线程("Stop-The-World"),它的优点是简单高效(与其他收集器的单线程比),适用于单核处理器的环境。
2、 ParNew收集器:可以看作是Serial收集器的多线程版本,主要用于新生代的垃圾收集,适合多核处理器环境。
3、 Parallel Scavenge收集器:也是一个新生代垃圾收集器,使用多线程收集,注重吞吐量(CPU用于运行用户代码的时间比率)。
4、 Serial Old收集器:是Serial收集器的老年代版本,单线程,采用标记-整理算法。
5、 Parallel Old收集器:是Parallel Scavenge收集器的老年代版本,使用多线程并行收集,目标是提高系统吞吐量。
6、 CMS(Concurrent Mark Sweep)收集器:以获取最短回收停顿时间为目标,使用多线程并发标记和清除算法。
7、 G1(Garbage-First)收集器:采用分区堆(Heap)和增量式垃圾回收,目标是兼顾吞吐量和停顿时间。
JVM中的类加载器有哪些,它们各自的作用是什么?
JVM中的类加载器主要有三种:
1、启动类加载器(Bootstrap ClassLoader) :它负责加载存放在<JAVA_HOME>/jre/lib目录中,或者被-Xbootclasspath参数指定的路径中的类库。
2、扩展类加载器(Extension ClassLoader) :它负责加载<JAVA_HOME>/jre/lib/ext目录中的类库。
3、应用程序类加载器(Application ClassLoader) :它负责加载用户类路径(Classpath)上所指定的类库。
每个类加载器都有其特定的加载范围,这种层次关系保证了Java程序稳定运行。
JVM中垃圾回收的算法有哪些?
JVM垃圾回收的主要算法包括:
1、标记-清除算法(Mark-Sweep) :先标记出所有需要回收的对象,然后统一清除这些对象。
2、复制算法(Copying) :将内存分为两块,每次只使用其中一块,当这一块的内存用完了,就把还活着的对象复制到另一块上去。
3、标记-整理算法(Mark-Compact) :类似于标记-清除算法,但在清除后会进行内存整理,减少碎片。
4、分代收集算法(Generational Collection) :根据对象存活周期的不同将内存划分为几块,如年轻代、老年代等,采用适合各个年代的收集算法。
JVM如何判断对象是否死亡?
JVM判断对象是否死亡主要有两种方式:
1、引用计数法:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
2、可达性分析:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
JVM中有哪些引用类型?
JVM中主要有四种引用类型:
1、强引用(Strong Reference) :普通的对象引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象。
2、软引用(Soft Reference) :内存不足时,会被垃圾回收器回收掉。
3、弱引用(Weak Reference) :只能生存到下一次垃圾收集之前,当垃圾回收器工作时,无论内存是否足够,都会回收掉只被弱引用关联的对象。
4、虚引用(Phantom Reference) :最弱的一种引用关系,无法通过虚引用来获取对象实例,它的存在仅仅是为了在这个对象被收集器回收时收到一个系统通知。
JVM的永久代(PermGen)和元空间(Metaspace)有什么区别?
永久代(PermGen)和元空间(Metaspace)是JVM中存储类元数据的区域,二者的主要区别如下:
1、存储位置:永久代是在JVM的堆内存中,而元空间位于本地内存。
2、大小限制:永久代的大小是固定的,容易出现内存溢出;元空间利用本地内存,所以默认情况下只受本地内存大小限制。
3、回收机制:永久代的回收主要针对常量池的回收和对类型的卸载;元空间提供了更好的性能,在使用本地内存的同时,减少了垃圾收集的频率。
JVM中的堆和栈有什么区别?
堆和栈是JVM中两个重要的内存区域,它们的主要区别如下:
1、用途:堆用于存储对象实例和数组,是垃圾回收的主要区域;栈用于存储局部变量、操作数栈和控制流。
2、线程共享性:堆是被所有线程共享的内存区域,而栈是线程私有的。
3、内存分配:堆的内存分配是动态的,适用于动态对象的存储;栈的内存分配是连续的,适用于临时变量的存储。
4、内存回收:堆的内存回收由垃圾回收器处理,栈的内存分配和回收是自动的。
JVM中Full GC触发的原因有哪些?
Full GC触发的原因主要有以下几点:
1、老年代空间不足:老年代存放长期存活的对象,当老年代空间不足时,会触发Full GC。
2、永久代或元空间不足:当存储类元数据的区域空间不足时,同样会触发Full GC。
3、System.gc()调用:系统调用System.gc()时,通常会触发Full GC。
4、JVM参数:由于某些JVM参数设置不当,如过小的堆空间,也可能触发Full GC。
5、Eden区、Survivor区向老年代晋升失败:如果Eden区或Survivor区中的对象在Minor GC后仍然存活,并且老年代无法容纳这些对象,也会触发Full GC。
JVM中的类加载器有哪些,它们各自的作用是什么?
JVM中的类加载器主要有以下几种:
1、启动类加载器(Bootstrap ClassLoader): 加载Java的核心库(JAVA_HOME/jre/lib/rt.jar等),是所有类加载器的父加载器。
2、扩展类加载器(Extension ClassLoader): 加载JAVA_HOME/jre/lib/ext目录中或者由java.ext.dirs系统属性指定的路径中的类库。
3、应用程序类加载器(Application ClassLoader): 加载用户类路径(Classpath)上的类库,如果应用中没有定义自己的类加载器,这将是默认的类加载器。
每个类加载器都有自己的职责范围,确保Java应用能够加载类的灵活性和安全性。
JVM内存区域划分及其作用是什么?
JVM的内存区域主要包括:
1、方法区(Method Area): 存储类信息、常量、静态变量等。
2、堆(Heap)