JVM(完成度95%,不断更新) (11)

image.png


一个案例理解GC Roots

假设我们现在有三个实体,分别是 人,狗,毛衣
然后他们之间的关系是:人 牵着 狗,狗穿着毛衣,他们之间是强连接的关系
有一天人消失了,只剩下狗狗 和 毛衣,这个时候,把人想象成 GC Roots,因为 人 和 狗之间失去了绳子连接,
那么狗可能被回收,也就是被警察抓起来,被送到流浪狗寄养所
假设狗和人有强连接的时候,狗狗就不会被当成是流浪狗

/** * 在Java中,可以作为GC Roots的对象有: * - 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中的引用对象 * - 方法区中的类静态属性引用的对象 * - 方法区中常量引用的对象 * - 本地方法栈中的JNI(Native方法)的引用对象 */ public class GCRootDemo { // 方法区中的类静态属性引用的对象 // private static GCRootDemo2 t2; // 方法区中的常量引用,GC Roots 也会以这个为起点,进行遍历 // private static final GCRootDemo3 t3 = new GCRootDemo3(8); public static void m1() { // 第一种,虚拟机栈中的引用对象 GCRootDemo t1 = new GCRootDemo(); System.gc(); System.out.println("第一次GC完成"); } public static void main(String[] args) { m1(); } }

如何判断常量、类被废弃了

image.png


十一、强引用、软引用、弱引用、虚引用

概念列表 强引用
StrongReference 当内存不足的时候,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,打死也不回收~!
强引用是我们最常见的普通对象引用,只要还有一个强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到,JVM也不会回收,因此强引用是造成Java内存泄漏的主要原因之一。
对于一个普通的对象,如果没有其它的引用关系,只要超过了引用的作用于或者显示地将相应(强)引用赋值为null,一般可以认为就是可以被垃圾收集的了(当然具体回收时机还是要看垃圾回收策略)
软引用
SoftReference
  软引用是一种相对弱化了一些的引用,需要用Java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集,对于只有软引用的对象来讲:
- 当系统内存充足时,它不会被回收
   

当系统内存不足时,它会被回收

软引用通常在对内存敏感的程序中,比如Mybatis高速缓存就用到了软引用,内存够用 的时候就保留,不够用就回收 | 它们的区别主要在于GC时对对象回收时:软引用指向的对象只在内存不足时被回收,而只被弱引用指向的对象在下一次GC时被回收
 弱/软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中,进行其他与该对象相关内存的回收,如HashMap中的Key被回收,则Entry应该被回收。这就是JVM的工作了。
       弱引用对于构造弱集合最有用,如WeakHashMap ,它对键(而不是值)使用弱引用。
      软引用解决图片缓存的问题
      弱应用解决HashMap中的oom问题 |
| 弱引用
WeakReference | 不管内存是否够,只要有GC操作就会进行回收
弱引用需要用 java.lang.ref.WeakReference 类来实现,它比软引用生存期更短
对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存空间是否足够,都会回收该对象占用的空间。 | |
| 虚引用
PhantomReference | 虚引用又称为幽灵引用,需要java.lang.ref.PhantomReference 类来实现
顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。
如果一个对象持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列ReferenceQueue联合使用。
虚引用的主要作用和跟踪对象被垃圾回收的状态,仅仅是提供一种确保对象被finalize以后,做某些事情的机制。
PhantomReference的get方法总是返回null,因此无法访问对象的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作
换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候,收到一个系统通知或者后续添加进一步的处理,Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前,做必要的清理工作
这个就相当于Spring AOP里面的后置通知

一般用于在回收时候做通知相关操作

| |

代码实现

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsdps.html