zoukankan      html  css  js  c++  java
  • Strong/Soft/Weak/Phantom

    Strong Reference 强引用

    在我们的代码里,这样的引用是强引用。

    StringBuffer buffer = new StringBuffer();

    那么什么时候强引用太强了呢,导致它引用的对象无法被清除,最后导致内存溢出(OutOfMemoryError)。我们来看一个缓存的例子。

    例子1,

    public class ReferenceTest {
        //private Map map = new WeakHashMap();

        //Strong Reference Map
        private Map map = new HashMap();
       
        @Before
        public void setup() throws IOException{
            for(int i=0 ; i <10 ; i++) {
                BufferedImage img = ImageIO.read(new File("D:\\Lenovo4-2.jpg"));
                map.put("img"+i, img);
            }
        }
       
        @Test
        public void getFromMap(){
            new Thread(){
                public void run(){
                    int i = 0;
                    while(i<10) {
                        i ++;
                        Object o = map.get("img"+1);
                        System.out.println(o);
                    }
                }
            }.start();
        }
    }

    以上的程序在vm 参数-Xmx20m时运行出现OutOfMemoryError, 但是把HashMap换成WeakMap的时候就不会出现这种情况。

    出现以上这种情况的原因是,当使用强引用的时候JVM不能够回收map引用的对象。

    但是WeakMap不一样,以上例子中由于map对象已经被回收,同时map里的对象都是弱引用(WeakReference), map中的对象也被回收。

    Soft Reference 软引用

    SoftReference的引用强度比WeakReference强一些,它不是那种要么全有,要么全无的引用。软引用的对象会不会被垃圾回收决定于JVM内存在使用情况。我们把大数据放在列表中,比如

    http://www.ibm.com/developerworks/java/library/j-jtp01246/index.html

    例子2,

    public class SoftReferenceTest {
        private List<BufferedImage> imgs;

        @Before
        public void setup() throws IOException {
            imgs = new ArrayList<BufferedImage>();
            for (int i=0; i< 10; i++) {
                BufferedImage img = ImageIO.read(new File("D:\\Lenovo4-2.jpg"));
                imgs.add(img);
            }
        }

        @Test
        public void getSoftReferedObject() {
            for (BufferedImage img : imgs){
                System.out.println(img);
            }
        }
    }

    以上的代码在VM参数为-Xmx20m的情况下出现OutOfMemoryError,但是换成以下代码就不会

    public class SoftReferenceTest {

        private List<SoftReference<BufferedImage>> imgs;

        @Before
        public void setup() throws IOException {
            imgs = new ArrayList<SoftReference<BufferedImage>>();
            for (int i=0; i< 10; i++) {
                SoftReference<BufferedImage> img = new SoftReference<BufferedImage>(ImageIO.read(new File("D:\\Lenovo4-2.jpg")));
                imgs.add(img);
            }
        }

        @Test
        public void getSoftReferedObject() {
            for (SoftReference<BufferedImage> img : imgs){
                System.out.println(img.get());
            }
        }

    }

    我们在用SoftReference的时候要判断引用的对象是不是空。

    Weak Reference 弱引用

    http://www.ibm.com/developerworks/java/library/j-jtp11225/index.html

    上面的例子1 WeakHashMap是WeakReference的一个应用。

    Phantomo Reference 幻影引用

    幻影引用又区别与软引用和弱引用。我们甚至 不能像SoftReference或者WeakReference一样通过get方法得到被引用对象--调用get方法永远返回空。幻影引用的作用在于:第一能够通过它判断一个对象已经被垃圾回收;第二,避免重写finalize方法以复活对象时,为这些对象创建强引用。

    Java区分引用(Strong,Soft,Weak,Phathom)有什么用?

    让垃圾回收器更好地管理内存,防止潜在的内存泄露。

    Original explanation

    http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

  • 相关阅读:
    MPI消息传递MPI_Sendrecv的用法
    外网SSH访问内网LINUX服务器
    LINUX下Doxygen的配置与使用
    C语言中关键字const一般的用途
    Ubuntu使用apt-get时提示>”E: You must put some ‘source’ URIs in your sources.list”
    C语言中复数运算及调用blas,lapack中复数函数进行科学计算
    linux系统下C语言调用lapack ,blas库
    一封家书,道尽顶尖人才的思维境界
    学会用麦肯锡的方式思考
    记得自己的大梦想
  • 原文地址:https://www.cnblogs.com/cando/p/2287769.html
Copyright © 2011-2022 走看看