码迷,mamicode.com
首页 > 编程语言 > 详细

java之内存泄露

时间:2015-04-18 14:34:59      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:内存   java   程序开发   程序员   内存泄露   

一、过期引用导致的内存泄露
注意:当对象不使用后将对象设置为null,这个时候虚拟机不一定释放该内存,至于什么时候释放由垃圾回收算法确定。
当对象不在使用时,而不回收有可能出现内存泄露的问题。在Effective Java里面有一条建议,消除过期的对象引用。
实例:JDK中栈的内存优化问题
1、消除过期对象引用的原因(出现内存泄露的原因):随着栈的增加,然后再收缩,从栈中出来的对象将不会被回收,即使程序不在引用这些对象。
因为,在栈的内部维护着这些对象的过期引用(过期引用就是永远不会被解除的引用)。
2、内存泄露过程:随着垃圾回收器的活动,或者说内存占用的不断增加,程序的性能变低会慢慢显示出来。在极端的情况下,程序很容易出现OOM的错误。
下面的程序模拟JDK中Stack的实现:
public class MyStack {
	private Object[] elements;// 栈用来装元素的
	private int size = 0;// 栈的大小
	private static final int DEFALT_INITIAL_CAPACITY = 16;
	
	
	public MyStack(){
		elements = new Object[DEFALT_INITIAL_CAPACITY];
	}
	
	/*
	 * 入栈
	 */
	public void push(Object e) {
		ensureCapacity();
	}
	
	/**
	 * 出栈
	 */
	public Object pop() {
		if(size==0)
			throw new EmptyStackException();
		return elements[--size];
	}


	/**
	 * 动态扩展栈的空间,确保栈中有足够的空间
	 */
	private void ensureCapacity() {
		if(elements.length==size) {
			elements = Arrays.copyOf(elements, 2*size+1);
		}
	}
}
二、hashCode与内存泄露:
public class MemoryLeakDemo {


	public static void main(String[] args) {
		Point p1 = new Point(1,2);
		Point p2 = new Point(3,4);
		Point p3 = new Point(3,6);
		Collection<Point> c = new HashSet<Point>();
		c.add(p1);
		c.add(p2);
		c.add(p3);
		c.add(p1);
		System.out.println("原来的对象数量:"+c.size());
	    // p1.setX(5);
	    c.remove(p1);
	    System.out.println("处理后的对象数量:"+c.size());// 原来有三个对象,删除后还有两个,打开上面的注释后,变成三个。
	}


}


class Point {
	private int x;
	private int y;
	
	public Point(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}


	public int getX() {
		return x;
	}


	public void setX(int x) {
		this.x = x;
	}


	public int getY() {
		return y;
	}


	public void setY(int y) {
		this.y = y;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Point other = (Point) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}
}
  原来有3个对象,删除后还有2个,打开上面的注释后,变成3个。为什么会对象删不掉呢?因为修改hashCode后,这个对象所在存储区域发生变化(哈希查找基本思路:通过计算对象的哈希码,然后进行哈希码分组,将对象存储到不同的区域,当需要对象时只需通过哈希码就可以确定对象属于哪个存储区域,从而加快了查找效率),执行remove方法后对象没有被删除,所以仍然是这么多元素。因为不用的对象占着内存不释放,所以出现了内存泄露的问题。那么,随着增删操作元素的次数不断增加,内存的耗用越来越大,从而导致程序异常结束。

java之内存泄露

标签:内存   java   程序开发   程序员   内存泄露   

原文地址:http://blog.csdn.net/u010213127/article/details/45113093

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!