java之内存泄露

来源:互联网 发布:淘宝5金冠童装店铺排行 编辑:程序博客网 时间:2024/05/20 14:26
一、过期引用导致的内存泄露
注意:当对象不使用后将对象设置为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;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic 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方法后对象没有被删除,所以仍然是这么多元素。因为不用的对象占着内存不释放,所以出现了内存泄露的问题。那么,随着增删操作元素的次数不断增加,内存的耗用越来越大,从而导致程序异常结束。
0 0
原创粉丝点击