Java垃圾回收

Java垃圾回收

Scroll Down

GC 是什么? 为什么要有 GC?

GC就是垃圾收集的意思(Gabage Collection), 我们在开发中会创建很多对象,这些对象一股脑的都扔进了堆里,如果这些对象只增加不减少,那么堆空间很快就会被耗尽。所以我们需要把一些没用的对象清理掉。

简单说一下java的垃圾回收机制。

java采用分代回收,分为年轻代、老年代、永久代。年轻代又分为E区、S1区、S2区。
到jdk1.8,永久代被元空间取代了。
年轻代都使用复制算法,老年代的收集算法看具体用什么收集器。默认是PS收集器,采用标记-整理算法。

JVM的常见垃圾回收算法有哪些?

复制、标记清除、标记整理、分代回收

为什么要使用分代回收机制?

因为没有一种算法能适用所有场合。在对象存活率低的场景下,复制算法最合适。
对象存活率高时,标记清除或者标记整理算法最合适。
所以才需要分代来处理。

如何判断一个对象是否存活?

现在主流使用的都是可达性分析法。从GC Roots对象计算引用链,能链上的就是存活的

如果对象的引用被置为 null,垃圾收集器是否会立即释放对象占用的内存?

不会。对象回收需要一个过程,这个过程中对象还能复活。而且垃圾回收具有不确定性,指不定什么时候开始回收。

Java中判断对象死亡有两种方式

引用计数法

引用计数法的思想十分朴素,它的做法是给对象添加一个引用计数器,每当有一个地方引用该对象,这个计数器就加1。当引用失效时,计数器就减1。如果计数器为0了,说明该对象不再被引用,成为死亡对象。不过这种算法有一个致命缺点,就是无法处理对象相互引用的情况。

你看,假如有A、B两个对象,它们互相引用,那么对象中的引用计数器会始终大于0。

所以这种算法已经没人用了。

可达性分析法

可达性分析法就是目前的主流算法,也是java正在使用的算法, 它的做法是,通过一系列被称为“GC Roots”的对象作为起点,从这些起点开始往下搜索,搜索所走过的路径称为引用链(Reference Chain)。当一个对象没有和任何引用链相连,即称为该对象不可达,认为该对象死亡

GC Roots:

  • 栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI引用的对象

GC Roots是所有Java线程中处于活跃状态的栈帧,静态引用等指向GC堆里的对象的引用。换句话说,就是当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。

引用分类

强引用: String str = new String("hello"); 只要强引用还在,对象就不会被回收

软应用: SoftReference<String> str = new SoftReference<String>("hello"); 内存不足时会被回收

弱引用: WeakReference<String> str = new WeakReference<String>("hello"); 每次GC时都会被回收

虚引用: PhantomReference<String> str= new PhantomReference<>(new String("hello"), new ReferenceQueue<>());获取时总是返回null, 唯一的作用是在对象被回收时发一个系统通知

方法区回收

jdk1.8中虽然永久代被取消,但是新增了MaxMetaspaceSize参数,对于将死的类及类加载器的垃圾回收将在元数据使用达到“MaxMetaspaceSize”参数的设定值时进行

垃圾回收算法

  • 标记-清除算法
  • 复制算法
  • 标记-整理算法
  • 分代回收算法

标记-清除算法

标记-清除算是最基本的回收算法。它的思想就是先标记,再清除

它的主要缺点有两个:

  • 效率不高
  • 会产生大量内存碎片

复制算法

复制算法的思想是,把内存分成两块,假设分成A、B两个区域。

每次对象过来之后,都放到A区域里,当A区域满了之后,把存活的对象复制到B区域,然后清空A区域。接下来的对象就全部放到B区域,等B区域满了,就把存活对象复制到A区域,然后清空B区域

优点是不会有空间碎片缺点是每次只用得到一半内存

缺点是在对象存活率较高的场景下(比如老年代那样的环境),需要复制的东西太多,效率会下降

标记整理算法

标记-整理算法中的“标记”阶段和“标记-清理”中的标记一样。不同的是,死亡对象并不会直接清理,而是把他们在内存中都移动到一起,然后一起清理。

分代回收算法

java中使用的就是分代收集算法。

存活率低的对象放在一起,称为年轻代,使用复制算法来收集。

存活率高的对象放在一起,称为老年代,使用标记-清除或者标记-整理算法。