首页 科技正文

ug环球网址:【JVM】若何明白强引用、软引用、弱引用、虚引用?

admin 科技 2020-06-02 36 0

整体架构

强引用

强引用是默认支持,当内存不足的时刻,JVM最先垃圾接纳,对于强引用的工具,就算是泛起了OOM也不会接纳工具。

强引用是最常见的通俗工具引用,只要另有强引用指向工具,工具就存活,垃圾接纳器不会处置存活工具。一样平常把一个工具赋给一个引用变量,这个引用变量就是强引用。当一个工具被强引用变量所引用,它就处于可达状态,是不会被垃圾接纳的,纵然之后都不会再用到了,也不会接纳。因此强引用是造成Java内存泄露的主要原因之一

关于Java内存泄露的详细内容,可以参考这篇博客:https://blog.csdn.net/m0_38110132/article/details/81986334。

对于一个通俗工具,若是没有其他引用关系,只要超过了引用的作用域或者显式地将响应的强引用赋值为null,一样平常以为就是可以被垃圾接纳了。(详细的接纳时机看垃圾接纳计谋)

下例中,b就是强引用。

1     public static void main(String[] args) {
2         Object a = new Object();
3         Object b = a;
4         a = null;
5         System.out.println(b);//java.lang.Object@4554617c
6     }

软引用

软引用是一种相对强引用弱化了一些的引用,用java.lang.ref.SoftReference实现,可以让工具宽免一些垃圾网络。当系统内存足够的时刻,不会被接纳;当系统内存不足的时刻,会被接纳。

软引用一样平常用于对内存敏感的程序中,好比高速缓存。

 1 import java.lang.ref.SoftReference;
 2 
 3 public class SoftReferenceDemo {
 4     public static void main(String[] args) {
 5         Object a = new Object();
 6         SoftReference<Object> softReference = new SoftReference<>(a);//软引用
 7         //a和软引用指向同一个工具
 8         System.out.println(a);//java.lang.Object@4554617c
 9         System.out.println(softReference.get());//java.lang.Object@4554617c
10 
11         //内存够用,软引用不会被接纳
12         a = null;
13         System.gc();//内存够用不会自动gc,手动叫醒gc
14         System.out.println(a);//null
15         System.out.println(softReference.get());//java.lang.Object@4554617c
16 
17         //内存不够用时
18         try{
19             //设置Xms和Xmx为5MB
20             byte[] bytes = new byte[1024*1024*30];//设置30MB超内存
21         }catch (Throwable e){
22             e.printStackTrace();
23         }finally {
24             System.out.println(a);//null
25             System.out.println(softReference.get());//null
26         }
27     }
28 }

使用场景

一个应用需要读取大量的内陆图片,若是每次读取都从硬盘读取会严重影响性能,若是一次性所有加载到内存,内存可能会溢出。

可以使用软引用解决这个问题,使用一个HashMap来保留图片路径和图片工具治理的软引用之间的映射关系,内存不足时,JVM会自动接纳缓存图片工具的占用空间,有效地避免了OOM(Out Of Memory)问题。

Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>

弱引用

弱引用需要用java.lang.ref.WeakReference实现,它比软引用的生存期更短,对于弱引用的工具来说,只要垃圾接纳机制一运行,不管JVM的内存空间是否够,都市接纳该工具的占用内存。

 1 import java.lang.ref.WeakReference;
 2 
 3 public class SoftReferenceDemo {
 4     public static void main(String[] args) {
 5         Object a = new Object();
 6         WeakReference<Object> softReference = new WeakReference<>(a);//软引用
 7         //a和弱引用指向同一个工具
 8         System.out.println(a);//java.lang.Object@4554617c
 9         System.out.println(softReference.get());//java.lang.Object@4554617c
10 
11         //内存够用,弱引用也会被接纳
12         a = null;
13         System.gc();//内存够用不会自动gc,手动叫醒gc
14         System.out.println(a);//null
15         System.out.println(softReference.get());//null
16     }
17 }

关于WeakHashMap

 1     public static void weakHashMapTest() {
 2         Integer key = new Integer(1);
 3         String value = "李四";
 4         Map<Integer,String> weakHashMap = new WeakHashMap();
 5         weakHashMap.put(key, value);
 6         System.out.println(weakHashMap);//{1=李四}
 7         key = null;
 8         System.gc();
 9         System.out.println(weakHashMap);//{}
10     }
11 
12     public static void hashMapTest() {
13         HashMap<Integer,String> map = new HashMap<>();
14         Integer key = 1;
15         String value = "张三";
16         map.put(key,value);
17         System.out.println(map);//{1=张三}
18         key = null;
19         System.gc();
20         System.out.println(map);//{1=张三}
21     }

在HashMap中,键被置为null,叫醒gc后,不会垃圾接纳键为null的键值对。但是在WeakHashMap中,键被置为null,叫醒gc后,键为null的键值对会被接纳。

虚引用

虚引用要通过java.lang.ref.PhantomReference类来实现,虚引用不会决议工具的生命周期,若是一个工具只有虚引用,就相当于没有引用,在任何时刻都可能会被垃圾接纳器接纳。它不能单独使用也不能接见工具,虚引用必须和引用行列团结使用

虚引用的主要作用是跟踪工具被垃圾接纳的状态,仅仅是提供一种确保工具被finalize以后,做某些事情的机制。

PhantomReference的get方式总是返回null,因此无法接见对应的引用工具,设置虚引用关联唯一的目的是在工具被网络器接纳的时刻收到一个系统通知,或者后续添加进一步的处置。Java允许使用finalize()方式在垃圾接纳器将工具从内存中清算出去之前做一些需要的清算事情。【例如实现一个监控工具的通知机制】

引用行列

WeakReference和ReferenceQueue的团结使用效果:

 1     public static void weakReferenceTest() {
 2         Object a = new Object();
 3         ReferenceQueue<Object> queue = new ReferenceQueue<>();
 4         WeakReference<Object> weakReference = new WeakReference<>(a,queue);
 5         System.out.println(a);//java.lang.Object@4554617c
 6         System.out.println(weakReference.get());//java.lang.Object@4554617c
 7         System.out.println(queue.poll());//null
 8         System.out.println("-------------------");
 9         a = null;
10         System.gc();
11         System.out.println(a);//null
12         System.out.println(weakReference.get());//null
13         //虚引用在接纳之前被加入到了引用行列中
14         System.out.println(queue.poll());//java.lang.ref.WeakReference@74a14482
15     }

PhantomReference和ReferenceQueue的团结使用效果:

 1     public static void phantomReferenceTest() {
 2         Object a = new Object();
 3         ReferenceQueue<Object> queue = new ReferenceQueue<>();
 4         PhantomReference<Object> phantomReference = new PhantomReference<>(a,queue);
 5         System.out.println(a);//java.lang.Object@4554617c
 6         System.out.println(phantomReference.get());//null
 7         System.out.println(queue.poll());//null
 8         System.out.println("-------------------");
 9         a = null;
10         System.gc();
11         System.out.println(a);//null
12         System.out.println(phantomReference.get());//null
13         //引用在接纳之前被加入到了引用行列中
14         System.out.println(queue.poll());//java.lang.ref.WeakReference@74a14482
15     }

总结

强引用:不接纳。

软引用:内存不够就接纳。

弱引用:一定接纳。

虚引用:一定接纳,get出来就是null,引用形同虚设,主要和引用行列团结使用,在finalize之前会被放到引用行列中。

与根工具没有引用关系的:引用不可达,一定接纳。

,

欧博网址开户

www.cx11zx.cn欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

版权声明

本文仅代表作者观点,
不代表本站dafa888的立场。
本文系作者授权发表,未经许可,不得转载。

评论