在 java 中,那些情况下的对象会被垃圾回收机制处理掉?
在 Java 中,垃圾回收机制会自动处理掉不再被引用的对象。一般来说,对象可以通过下面两种方式被认为是垃
圾:
1. 引用计数法:该对象的引用计数为 0,即没有任何其他对象引用该对象
2. 可达性分析法:该对象没有任何与之相连的引用链,即无法从 GC Roots 遍历到该对象
在 java 中,那些对象可以被看做是 GC Roots 呢?
在 Java 中,能够被视为 GC Roots 的对象包括以下几种:
1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
2. 方法区中类静态属性引用的对象
3. 方法区中常量引用的对象
4. 本地方法栈中 JNI(即一般所说的 Native 方法)引用的对象
GC Roots 通常是程序运行过程中必须保持的对象,它们存放在堆以外,是 Java 虚拟机的内部对象,也是垃圾
回收器判断一个对象是否可用的起点。因此,在进行垃圾回收时,只有从 GC Roots 开始搜索,才有可能找到
所有需要回收的对象。
谈谈 JVM 常见的几种垃圾收集算法?
Java 虚拟机(JVM)为了管理堆内存中的对象,进行了垃圾收集。垃圾收集算法按照不同的策略、实现方式、
适用场景等进行分类。下面介绍 Java 的 JVM 常见的几种垃圾收集算法:
1. 标记-清除算法(Mark-Sweep)
标记-清除算法是最基础的垃圾收集算法,它分两个阶段:标记和清除。
在标记阶段,从根节点开始遍历所有可达对象,并对这些对象做上标记。然后,在清除阶段,将没有标记的对
象(即未被引用的对象)回收。
缺点:会产生大量内存碎片,且效率不高。
2. 复制算法(Copying)
复制算法将堆内存分成大小相等的两个区域,每次只使用其中一个区域。分配对象时,先在当前正在使用的区
域分配,当该区域的空间不足,就将该区域的存活对象复制到另一个区域,再把原来的区域全部清空。举例来
说,如果当前使用的区域是 A 区,那么在进行垃圾收集时,会将已经标记好的存活对象复制到 B 区,并将 A 区
重新清空,交换两个区的角色。这样就保证了每次垃圾收集后都有能够存放对象的干净的内存区域。
优点:避免了标记-清除算法中的内存碎片问题,并且效率较高。
缺点:需要一块同大小的空间进行复制,因此只适用于堆比较小的情况。
3. 标记-整理算法(Mark-Compact)
标记-整理算法也有两个阶段:标记和整理。在标记阶段,从根节点开始遍历所有可达对象,并对这些对象做上
标记。在整理阶段,将所有存活的对象都向堆的一端移动,然后回收另一端的所有空间。
优点:可以解决复制算法的空间浪费问题,同时也避免了标记-清除算法中的内存碎片问题。
缺点:垃圾收集过程中需要移动对象,因此效率相对较低。