Java内存泄露实例代码

内存泄露本质:长生命周期的对象持有了短生命周期的对象的引用。

减少内存泄露风险方式:

1.单例模式。 单例模式一般都是全局静态持有,所以需要注意,尽量不要在单例中持有大对象。

2.遇到大对象的时候,用完及时设为null。

3.对象尽可能的减小其生命周期。

4.I/O流用完一定要关闭。如文件流、socket流、数据库连接等

5.引用类型的数组中某个元素不再需要的时候,一定要设为null

下面为可能会出现内存泄露的代码:

1.使用HashSet集合的情况。由于set是不重复的,更新操作会先通过hashcode来查找,然后通过equels来判断是否相等。

   默认hashcode 和equels方法: 在更新类中的字段值,不会造成内存泄露

   重写hashcode 和equels方法: 重写后这两个方法一般都是随着类中的字段值hashcode也跟随着变化,在删除更新后的对象时,可能会造成内存泄露(hashcode变化,找不到该对象了)

public class SetMemLeak {

    private final static Set<Stock> stockSet = new HashSet<Stock>();

    public static void main(String[] args) {
        Stock stock1 = new Stock("300059.SZ", 12.5f, 13.1f);
        Stock stock2 = new Stock("600000.SH", 23.5f, 43.1f);

        int beforeHashcode = stock1.hashCode();
        stockSet.add(stock1);
        stockSet.add(stock2);
        int beforeSize = stockSet.size();
        stock1.setPclose(132.1f);   //
        int afterHashcode = stock1.hashCode();
        System.out.println("before:" + beforeHashcode + ";after:" + afterHashcode);
        //没有覆写:    before:200012267;after:200012267
        //覆写后输出:  before:1057581966;after:1086057358
        stockSet.remove(stock1);    //如果覆写equels 和hashcode方法, 这里将导致内存泄露
        int afterSize = stockSet.size();
        System.out.println("before size:" + beforeSize + ";after size:" + afterSize);
        //没有覆写:    before size:2;after size:1
        //覆写后输出:  before size:2;after size:2
    }
}

class Stock {
    private String stockCode;
    private float price;
    private float pclose;

    public Stock(String stockCode, float price, float pclose) {
        this.stockCode = stockCode;
        this.price = price;
        this.pclose = pclose;
    }

    public String getStockCode() {
        return stockCode;
    }

    public void setStockCode(String stockCode) {
        this.stockCode = stockCode;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public float getPclose() {
        return pclose;
    }

    public void setPclose(float pclose) {
        this.pclose = pclose;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Stock)) return false;

        Stock stock = (Stock) o;

        if (Float.compare(stock.pclose, pclose) != 0) return false;
        if (Float.compare(stock.price, price) != 0) return false;
        if (stockCode != null ? !stockCode.equals(stock.stockCode) : stock.stockCode != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = stockCode != null ? stockCode.hashCode() : 0;
        result = 31 * result + (price != +0.0f ? Float.floatToIntBits(price) : 0);
        result = 31 * result + (pclose != +0.0f ? Float.floatToIntBits(pclose) : 0);
        return result;
    }
}

 2

猜你喜欢

转载自ihenu.iteye.com/blog/2428360
今日推荐