zoukankan      html  css  js  c++  java
  • 指向对象的引用置空---与内存泄漏

    import java.util.Arrays;
    
    public class Stack {
        
        private static final int INIT_SIZE = 10;
    
        private Object[] datas;
        
        private int size;
    
        public Stack() {
            super();
            datas = new Object[INIT_SIZE];
        }
        
        public void push(Object data){
            if (size == datas.length) {
                extend();
            }
            datas[size++] = data;
        }
        
        public Object pop(){
            if (size == 0) {
                throw new IndexOutOfBoundsException("size is zero");
            }
            return datas[--size];
        }
        
        private void extend(){
            datas = Arrays.copyOf(datas, 2 * size + 1);
        }
        
    }

    上述代码,是从其他博客拷贝过来的。

    上述代码的意思:

    1.入栈,将指向某个对象的引用值,存放进来。

    2.出栈,将指向某个对象的引用值,返回给用户。

    潜在的问题:

        public Object pop(){
            if (size == 0) {
                throw new IndexOutOfBoundsException("size is zero");
            }
            return datas[--size];
        }
        
    

       这段代码的含义是,返回指向某个对象的引用值,然后,将栈顶向下移动。虽然是返回了某个对象的引用值,但是,数组中依然还保留着被返回的对象的引用值。这样的话,如果没有再进行入栈操作(用指向新的对象的引用值覆盖掉),那么,数组中就依然保留着被返回对象的引用值。

          而用户会觉得,既然某个对象已经出栈了,那么,该对象就不会还在栈中。而实际上,该对象还是在的,因为,datas数组中依然保留着指向该对象的引用值。如此,如果用户不再使用Stack进行入栈操作,那么,Stack就会一直保留着指向该对象的引用值。

           从而,也就出现了内存泄漏。对象依然存在在堆中,但用户并不知道,也不知道如何通过引用使用它。

           解决办法:每次返回某个指向对象的引用时,顺便将数组中保留的引用值置空,这样数组中就没有保存返回的对象引用值了。这样,GC在进行回时,就可以将该对象从堆中移除。

    public Object pop(){
            if (size == 0) {
                throw new IndexOutOfBoundsException("size is zero");
            }
            Object data = datas[--size];
            datas[size] = null;
            return data;
        }

        

            下面用具体例子展示:

            这样执行之后,用户以为stack中,已经没有指向a对象的引用了,实际上,还是有的。所以,堆上依然保留着a对象。

    public static void main(String[] args)
    {
    
        Object a = new Object();
    
         Stack stack = new Stack();
         stack.push(a);
         stack.pop();
         
          a = null;
    
    }
  • 相关阅读:
    asp.net mvc上传图片案例
    kafka 常用参数
    play framework 笔记
    调试 kafka manager 源码
    kafka AdminClient 闲时关闭连接
    kafka 心跳和 rebalance
    kafka producer batch 发送消息
    kafka producer 发送消息简介
    zk 的配额
    kafka consumer 指定 offset,进行消息回溯
  • 原文地址:https://www.cnblogs.com/ttylinux/p/3886687.html
Copyright © 2011-2022 走看看