什么是内存泄露
看到网上有很多人都在问内存泄露与内存溢出的区别(CSDN上),而且后面还有一大堆的跟帖在用不同形式的语言予以解答,我看了以后思绪万千啊。内存泄露是导致内存溢出的原因之一,说他们的区别纯属无稽之谈。要解释什么是内存泄露还真是个费事的活,我用一个例子来解释下:
-
如果是内存泄漏,可进一步通过工具查看泄漏对象到 GC Roots 的引用链。于是就能找到泄漏对象是通过怎样的路径与 GC Roots 相关联并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及 GC Roots 引用链的信息,就可以比较准确地定位出泄漏代码的位置。
-
如果不存在泄漏,换句话说就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx 与-Xms),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。
-
package outofmem;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
/**
-
* outofmemoryerror:其中之一
-
* 设置虚拟机堆的参数最小-Xms与最大-Xmx一样,避免堆自动扩展
-
* -Xms5m -Xmx5m
-
* 测试内存溢出
-
*/
-
-
public class TestMemOverflow {
-
static class OOMObject{
-
-
}
-
public static void main(String[]args){
-
List<OOMObject>list= new ArrayList<OOMObject>();
-
int i=0;
-
while(true){
-
list.add(new OOMObject());
-
System.out.println(i++);
-
}
-
-
}
-
-
}
上面的代码会不停的往list中添加数据,当我们的堆空间不足时,就会报OOM的错误,如下:
-
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
-
at java.util.Arrays.copyOf(Unknown Source)
-
at java.util.Arrays.copyOf(Unknown Source)
-
at java.util.ArrayList.ensureCapacity(Unknown Source)
-
at java.util.ArrayList.add(Unknown Source)
-
at outofmem.TestMemOverflow.main(TestMemOverflow.java:20)
当堆空间不足的时候,JVM会进行垃圾回收,但是垃圾回收时却发现这些对象都是有用的,不能回收。我们可能会考虑增大堆空间大小,可是这还是于是无补,因为我们有个死循环。这种情况其实就是内存泄露的一个简单例子,简而言之,如果是内存泄露引起的OOM,那肯定是我们代码有问题,需要修正代码。
阅读(5035) | 评论(3) | 转发(2) |