指向对象的引用置空---与内存泄漏

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;

}

指向对象的引用置空---与内存泄漏

时间: 2024-10-10 08:20:52

指向对象的引用置空---与内存泄漏的相关文章

[转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏

http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: #include<string> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> class parent; cl

block块中引用成员变量引起内存泄漏问题

使用block要注意循环引用,因此在块中使用self前先使用__weak修饰生产弱引用 这里记录另一种情况:没有使用属性而是直接使用成员变量的时候 // 私有成员变量 @implementation SmartInfoViewController { UIColor *lightColor; } // 在块中直接使用lightColor会造成retain cycle self.colBlock = ^(UIColor *col) { lightColor = col; // 等价于 self->

Android应用程序内存泄漏介绍

Android应用程序内存泄漏介绍 内存泄漏和内存溢出的区别 内存溢出(out of memory)是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory.比如在我们每个Android程序在运行时系统都会给程序分配一个一定的内存空间,当程序在运行中需要的内存超出这个限制就会报内存溢出(out of memory). 内存泄漏(memory leak)是指程序在申请内存后,无法释放已申请的内存空间.多次内存无法被释放,程序占用的内存会一直增加,直到超过系统的内存限制报内存

Java对象与引用

总结: 1. 基本数据类型的赋值不是引用,系统会自动创建两个独立的对象(内存空间) 2. 引用的赋值会覆盖两者在内存中的地址(即将两个对象合二为一),而基本数据类型的赋值不会 3. 引用存放在stack, 对象存放在heap.对象是引用的实体,我们日常看到的都是引用 对象引用 我们沿用之前定义的Human类,并有一个Test类: public class Test { public static void main(String[] args) { Human aPerson = new Hum

Android内存泄漏的本质原因、解决办法、操作实例

今年最后一个迭代终于结束了,把过程中碰到的不熟悉的东西拉出来学习总结一下 内存泄漏的本质是:[一个(巨大的)短生命周期对象的引用被一个长生命周期(异步生命周期)的对象持有] 这个东西分为两个部分 获得一个(巨大的)短生命周期的对象 这个[巨大的短生命周期的对象]在Android中最有可能的就是[Activity]了 最容易无意识获得它的方式就是[非静态内部类隐式自动持有外部类的强引用] 把这个对象赋值给了一个长生命周期的对象 这个有一些常见的套路 套路一:直接赋值给了一个类的静态成员 这个静态成

Java的内存泄漏_与C/C++对比(转载总结)

原文网址:http://developer.51cto.com/art/201111/302465.htm Java内存泄露的理解与解决(1) 一般来说内存泄漏有两种情况.一种情况如在C/C++ 语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值):另一种情况则是在内存对象已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用).第一种情况,在 Java 中已经由于垃圾回收机制的引入,得到了很好的解决.所以, Java 中的内存泄漏,主要

Android内存泄漏

韩梦飞沙  韩亚飞  [email protected]  yue31313  han_meng_fei_sha #Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.最近自己阅读了大量相关的文档资料,打算做个 总结 沉淀下来跟大家一起分享和学习,也给自己一个警示,以后 coding 时怎么避免这些情况,提高应用的体验

内存泄漏典型例子

Vector v = new Vector( 10 ); for ( int i = 1 ;i < 100 ; i ++ ){ Object o = new Object(); v.add(o); o = null ; }在这个例子中,代码栈中存在Vector 对象的引用 v 和 Object 对象的引用 o .在 For 循环中,我们不断的生成新的对象,然后将其添加到 Vector 对象中,之后将 o 引用置空.问题是当 o 引用被置空后,如果发生 GC ,我们创建的 Object 对象是否能

【转载】Android内存泄漏的8种可能

Java是垃圾回收语言的一种,其优点是开发者无需特意管理内存分配,降低了应用由于局部故障(segmentation fault)导致崩溃,同时防止未释放的内存把堆栈(heap)挤爆的可能,所以写出来的代码更为安全. 不幸的是,在Java中仍存在很多容易导致内存泄漏的逻辑可能(logical leak).如果不小心,你的Android应用很容易浪费掉未释放的内存,最终导致内存用光的错误抛出(out-of-memory,OOM). 一般内存泄漏(traditional memory leak)的原因