java 中会有内存泄露吗_Java:Java 中会存在内存泄漏吗

理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。

packagecom.dx.test;importjava.util.Arrays;importjava.util.EmptyStackException;public class MyStack{privateT[] elements;private int size = 0;private static final int INIT_CAPACITY = 16;publicMyStack() {

elements= (T[]) newObject[INIT_CAPACITY];

}public voidpush(T elem) {

ensureCapacity();

elements[size++] =elem;

}publicT pop() {if (size == 0)throw newEmptyStackException();return elements[--size];

}public intlength() {returnelements.length;

}public void test(inttop){

StringBuffer buffer=newStringBuffer();for(int i=0;i

buffer.append(elements[i]+",");

}

System.out.println(buffer.toString());

}private voidensureCapacity() {if (elements.length ==size) {

elements= Arrays.copyOf(elements, 2 * size + 1);

}

}

}

测试代码:

packagecom.dx.test;importjava.io.IOException;public classTestMain {public static void main(String[] args) throwsIOException {

System.out.println("start");

MyStack items = new MyStack();for (int i = 0; i < 100000; i++) {

items.push(i);

}for (int i = 0; i < 100000; i++) {

items.pop();

}

System.out.println(items.length());

items.test(100);

System.out.println("complete...");

}}

从打印结果中我们就可以发现问题:

start

139263

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,

complete...

上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值