Java对象的生命周期 引用 回收

1、垃圾回收器需要关注的内容

ava运行时内存区域的各个部分中,程序计数器、虚拟机栈、本地方法栈这三个区域的生命周期和线程相关,栈中的栈帧随着方法的进入和退出执行着进栈和出栈,每一个栈帧分配多少内存基本上在类的结构确定下来的时候就已经知道了,因此这3各区域的内存分配和回收都是确定的,因此不必过多考虑这三个区域的内存回收问题,因为方法结束后或者线程结束时,内存就会被自然回收。

java堆方法区则不一样(比如一个接口会有多个实现类,每个实现类需要的内存会不一样,一个接口方法的多个实现也是不一样的)我们只能在程序运行期间才能够知道会创建哪些对象,这部分的内存分配和回收都是动态的,垃圾回收器所关注的便是这部分内存。

2、对象的“存活”和“死亡”

堆里存放着java中几乎所有的对象实例,在垃圾回收器对堆进行回收前,判断对象的可用(存活)和不可用(死亡)是一件首要事情。判断对象的死亡有两种算法:1)引用计数算法;2)可达性分析算法;

java虚拟机中使用的是可达性分析算法,并没有使用引用计数算法,因为引用计数算法很难解决对象之间相互循环引用的问题。

1)引用计数算法

给对象加一个引用计数器,每当有一个地方引用该对象,引用计数器就增加1,当引用失效的时候就会减1,当引用计数器值为0的时候该对象可能就会处于不可用状态。OC上使用的便是引用计数算法。

2)可达性分析算法

主流商用语言java,C#的实现中都是通过可达性分析算法来判断对象是否存活的。该算法的基本思想就是通过一些列的称为GC Roots的对象作为起来,从这些节点向下搜索,搜索走过的路径称为引用链,,当一个对象到GC Roots没有任何引用链相连的时候,则证明此对象是不可用的。

java中可作为GC Roots的对象包括以下几种:

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

3、引用

强引用:一般的new关键之创建的对象的引用

软引用(SoftReference):描述一些有用但并非必须的对象,系统将要发生内存溢出之前,将会把这类对象列进回收范围中进行第二次回收,如果这次回收还是没有足够的内存才会抛出内存溢出异常。

弱引用(WeakReference):描述非必须的对象,之后能存活到下一次GC之前,只要当前垃圾回收器工作,无卵当前内存是否足够,都会被回收。

虚引用(PhantomReference):一个对象是否有虚引用存在不会影响其生存时间,无法通过虚引用来达到一个对象实例,对象设置虚引用关联的唯一目的是在这个对象被垃圾回收器回收的时候收到一个系统通知。JDK1.2之后提供了PhantomReference类来实现虚引用。

参考《深入理解Java虚拟机》

猜你喜欢

转载自blog.csdn.net/weixin_36709064/article/details/81903226