zoukankan      html  css  js  c++  java
  • 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强、软、弱引用总结:

  • 相关阅读:
    STM32F4xx时钟理解
    ubuntu突然卡住
    图像处理的面试问题汇总(6)
    更改IOS于UISearchBar撤消button底、搜索输入文本框背景中的内容和UISearchBar底
    PHP于DIRECTORY_SEPARATOR任务
    iOS8使用Core Graphics实现渐变效果-Swift基础教程
    iOS开发系列--打造自己的“美图秀秀”
    swiftTools
    如何把UIView转成UIImage,解决模糊失真问题
    Android清理内存
  • 原文地址:https://www.cnblogs.com/jxyedu/p/6241668.html
Copyright © 2011-2022 走看看