JAVA GC机制二

概述

通过上文我们了解到 程序计数器、虚拟机栈、本地方法栈这三个区域随线程而生,随线程而灭。这几个区域的内存的分配和回收都具备可确定性,因此不需要过多考虑内存回收的问题。

1、java堆

堆主要存储的是“对象”,因此在堆中我们回收的是“对象”

java堆中,一个接口中的多个实现类需要的内存可能不一样,一个方法的多个分支需要的内存也可能不一样,这些只有在程序运行期间才能知道创建的哪些对象,这部分内存的创建和回收都是动态的,所以大部分的垃圾回收也发生在这两个区域

首先我们来看 java堆

我们知道几乎所有的对象都存放在堆中,GC的一个功能就是清除一些不需要的对象,来为我们的虚拟机释放内存空间,哪些对象是需要被回收的呢

1.引用计数算法

给对象中添加一个引用计数器,每次引该对象,计数器就加1,引用失效后计数器减1,当它为0时就表示此对象时无用的对象。
但是会存在这样一个现象,就是A对象引用B,B对象引用A,但是A对象和B对象都不可能被访问,但是他们的计数器永远的为1,此时GC就无法的回收掉这部分的内存

2.可达性分析算法

这个算法的基本思路就是通过一系列的成为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,可以被回收的。

3.这里又引出了一个我们经常听到一个概念 java对象的引用类型

1、强引用(Strong Reference) 平时我们编程的时候例如:Object object=new Object();那object就是一个强引用了。如果一个对象具有强引用,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

2、软引用(Soft Reference) 用来描述一些还有用但不是必须的对象,如果一个对象只具有软引用,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。如果这次回收还没有足够的内存,才会抛出OutOfMemoryError错误

3、弱引用(Weak Reference)

弱引用也是用来描述非必须对象的,但是比软引用更弱一些,被弱引用关联的对象只能生存到下一次的垃圾回收之前。当垃圾回收工作时,无论当前内存足够,都会回收掉被弱引用关联的对象。

4、虚引用(Phantom Reference)
被称为幽灵引用,随时可能被回收,这里不过多描述

2、方法区

概述

方法区(或者HotSpot虚拟机中的永久代)与Java堆样,是各个线程共享的内存区域,‘用于存 储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%-80%的空间,而永久带的垃圾收集效率远低于此。
方法区的垃圾回收主要收集两个部分:废弃的常量和无用的类。回收废弃常量与回收java堆中的对象非常类似。

一个常量是否回收要同时满足以下三个条件:

(1)该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例
(2)加载该类的ClassLoader已经被回收
(3)该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
只有同时具备以上三个条件,常量才可以被回收,而不是和对象一样,不使用了就必然会回收。

你可能感兴趣的:(JAVA GC机制二)