01_Java 软、弱引用语法介绍

文章导读:

从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用, 本章内容介绍了Reference的概念和语法实现. 附件有源码下载

视频与源码下载:http://edu.51cto.com/lecturer/index/user_id-9166337.html  (代码在视频的附件中)

 

强引用(StrongReference) :

强引用是使用最普遍的引用. 如果一个对象具有强引用, 那垃圾回收器绝不会回收它,当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止, 也不会靠随意回收具有强引用的对象来解决内存不足的问题

1 public class RefDemo {
2 
3 // 强引用, JVM -Xms5M  -Xmx10M
4 public static void demo01(){
5     // 强引用,即使内存溢出,垃圾回收也不会回收此对象
6     byte[] b = new byte[1024*1024*10]; // 默认创建10MB的byte数组
7 }
8 }

为了方便测试首先要在JVM中配堆内存大小如图所示:

我们声明的 byte[] b = new byte[1024*1024*10] 是强引用类型,及时内存溢出GC也不会回收强引用的对象, 因此会抛出堆内存溢出

 

软引用(SoftReference):

软引用是除了强引用外, 最强的引用类型. 可以通过SoftReference使用软引用. 一个持有软引用的对象,不会被JVM很快回收. JVM会根据当前堆的使用情况来判断何时回收. 当堆的使用率接近临界点时, 才会去回收软引用的对象. 只要有足够的内存, 软引用变可以在内存中存货很长时间.因此, 软引用可以用于实现对内存敏感的cache

 1     // 软引用: 内存不够才会被回收,项目中的缓存
 2     public static void demo02(){
 3         MyObject myO=new MyObject();
 4         // 采用软引用存储
 5         SoftReference<MyObject> softRef=new SoftReference<MyObject>(myO);
 6         myO = null; //强引用已经失效
 7         // 手动调用垃圾回收,一般JVM自动调用
 8         System.out.println(softRef.get());
 9         System.gc(); // 如果内存足够,软引用是不会被回收的
10         System.out.println(softRef.get());
11         // 不断的填充堆空间,如果内存不够则回收
12         List<Object> oList=new ArrayList<Object>();
13         for(int i=1;i<=10;i++){
14             // 每次填充1MB
15             oList.add(new byte[1024*1024*1]);
16             System.out.println("当前虚拟机中的内存总量" + Runtime.getRuntime().totalMemory()/1024.00/1024 + "MB");
17             System.out.println("i:" + i);
18             // 软引用: 内存不够才会被回收
19             System.gc();
20         }
21     }

从运行结果我们可以看出, GC在内存不充足的时候才会回收软引用的空间. 但是回收的空间也不足以存储生成的数组对象,因此还是抛出了堆内存溢出

 

弱引用 (WeakReference):

弱引用是一种比软引用较弱的引用类型, 在系统GC时, 只要发现弱引用, 不管系统堆空间是否足够, 都会将对象进行回收. 但是由于垃圾回收器的线程通常优先级很低. 因此, 并不一定能很快发现持有的弱引用的对象. 在这种情况下. 弱引用对象可以存在较长时间.

 1 public class MyObject {
 2     @Override
 3     public String toString() {
 4         return "I am MyObject";
 5     }
 6     @Override
 7     protected void finalize() throws Throwable {
 8         super.finalize();
 9         System.out.println("MyObject's finalize called"); // 被回收时输出
10     }
11     public static void main(String[] args) throws InterruptedException {
12         MyObject obj = new MyObject();
13         WeakReference<MyObject> softRef = new WeakReference<MyObject>(obj); // 创建一个引用队列
14         System.gc();  // 因为还有强引用因此不能回收,一般在生产者模式下不会手动调用垃圾回收方法
15         System.out.println("获取弱引用:" + softRef.get());
16         obj = null;
17         System.gc();  // 无论空间是否充足都应该回收弱引用对象
18     }
19 }

我们会发现弱引用的对象,只要GC调用则就会被回收

 

Java强、软、弱引用总结:

posted @ 2017-01-10 07:44  Java、Android企培  阅读(381)  评论(0编辑  收藏  举报