zoukankan      html  css  js  c++  java
  • java 分析一道关于WeakReference的题目

    题目:

    import java.lang.ref.WeakReference;
    import java.util.WeakHashMap;
    
    public class Test1 {
        public static void main(String[] args) {
            String val = test();
            System.out.println("val:" + val);
        }
    
        private static String test(){
            String a = new String("a");
            WeakReference<String> b = new WeakReference<String>(a);
            WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, Integer>();
            weakMap.put(b.get(), 1);
            a = null;
            System.gc();
            String c = "";
            try{
                c = b.get().replace("a", "b");
                return c;
            }catch(Exception e){
                c = "c";
                return c;
            }finally{
                c += "d";
                return c + "e";
            }
        }
    }

    该题关键在考察WeakReferenceWeakHashMap的理解。

    先说下一点Java GC内容

      在Java里, 当一个对象object被创建时,它被放在Heap里。当GC运行的时候,如果发现没有任何引用指向object,object就会被回收以腾出内存空间。或者换句话说,一个对象被回收,必须满足两个条件:1)没有任何引用指向它 2)GC被运行.

    WeakReference

     当一个对象仅仅被weak reference(弱引用)指向, 而没有任何其他strong reference(强引用)指向的时候, 如果GC运行, 那么这个对象就会被回收。weak reference的语法是:

    WeakReference<T> weakref  = new WeakReference<T>();

    当要获得WeakReference的object时, 首先需要判断它是否已经被GC回收,若被收回,则下列返回值为空:

    weakref.get();

      所以在上述代码中,经过a=null; System.gc()后,当代码运行到c = b.get().replace("a", "b");时,由于b.get()为null,会抛出异常。

    WeakHashMap

      WeakHashMap其实和HashMap用法类似,它们之间唯一的区别就是:HashMap中的key保存的是实际对象的强引用,因此只要对象不被销毁,即该key所对应的key-value都不会被垃圾回收机制回收。但是WeakHashMap保存的实际对象是弱引用,这意味着只要该对象没有被强对象引用就有可能会被垃圾回收机制回收对应的Key-value。示例如下:

    import java.lang.ref.WeakReference;
    import java.util.WeakHashMap;
    
    public class WeakHashMapTest {
        public static void main(String[] args) {
            WeakHashMap weakMap = new WeakHashMap();
    
            //三个key-value中的key 都是匿名对象,没有强引用指向该实际对象
            weakMap.put(new String("语文"),new String("优秀"));
            weakMap.put(new String("数学"), new String("及格"));
            weakMap.put(new String("英语"), new String("中等"));
    
            //增加一个字符串的强引用
            weakMap.put("java", new String("特别优秀"));
    
            System.out.println(weakMap);
    
            //通知垃圾回收机制来进行回收
            System.gc();
            System.runFinalization();
    
            //再次输出w
            System.out.println("第二次输出:"+weakMap);
        }
    }

    所以在最开始的代码中WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, Integer>(); weakMap没有强引用指引,所以在执行System.gc()后weakMap被系统GC收回。

  • 相关阅读:
    [转]C#、VB.NET使用HttpWebRequest访问https地址(SSL)的实现
    C#设置System.Net.ServicePointManager.DefaultConnectionLimit,突破Http协议的并发连接数限制
    [转]WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键
    [转]C#打印DataGridView的例子源码
    c# TreeView 父节点选中/不选时子节点都同步选中/不选
    C#中PictureBox异步加载图片
    [转]FusionCharts 3.1 破解版 – 非常好用的Flash图表控件
    配合JavaScript拖动页面中控件
    在ThinkPad T400上安装win2003 所遇问题
    C# 抛弃MoveTo来实现文件重命名
  • 原文地址:https://www.cnblogs.com/myseries/p/12895296.html
Copyright © 2011-2022 走看看