内存泄露
所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。
java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收:
public class GarbageTest {
public static void main(String[] args) throws IOException {
try {
gcTest();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("has exited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begin gc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static void gcTest() throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2); //p1中包含p2的引用
p2.setMate(p1); //p2中包含p1的引用
System.out.println("before exit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exit gctest!");
}
private static class Person
{
byte[] data = new byte[20000000];
Person mate = null;
public void setMate(Person other)
{
mate = other;
}
}
}
当gcTest()方法运行完毕以后,p1和p2对象都变成了垃圾,他们都不会被根对象所找到。关于根对象请参见《JVM垃圾回收机制总结(2) :基本算法概述
》中的关于“垃圾回收从哪里开始”的讨论。
Java的内存泄露
虽然Java的垃圾回收机制较大程度的降低了内存泄露的可能性,但Java程序员仍然可能会写出发生内存泄露的代码。其原因就是一个已经不被使用的短寿命对象被一个长寿命对象(如类的静态成员对象)引用,这就使得本来要被回收的短寿命对象永远无法被回收,造成内存泄露。
内存泄露的典型情况
(1) 数据结构造成的短暂内存泄露问题,看下面的代码
public class Stack{
private Object[] element=new Object[10];
private int size=0;
public void push(Object ele){
ensureCapacity();
element[size++]=ele;
}
public Object pop(){
if(size==0) throw new EmptyStackException();
return element[--size]; //短暂造成内存泄露
}
private void ensureCapacity(){
if(element.length==size){
Object[] oldElement=element;
element=new Object[size*2+1];
System.arraycopy(oldElement,0,element,0,size);
}
}
}
上面的代码每一次pop()的时候,Stack都会弹出一个元素,在没有加入新元素之前,实际上仍然有一个引用element[x]指向了这个已经弹出的对象,因此GC是不会对其进行垃圾回收的。只有push()新元素的时候使得element[x]=newObject,才会使得以前创建的对象有可能被回收。应该把上面的pop()方法改成下面的代码就安全多了:
public Object pop(){
if(element.length==size) throws EmptyStackException();
Object o=element[--size];
elements[size]=null; //使得GC有机会回收这个对象
return o;
}
分享到:
相关推荐
关于JAVA内存泄漏问题注意事项.doc
如何解决Java内存泄漏
内存泄漏资料未整理内存泄漏资料未整理内存泄漏资料未整理
java内存泄漏解决java内存泄漏解决java内存泄漏解决
java内存泄露、溢出检查方法和工具。 步骤: 1,使用linux命令生存堆栈文件 2,用MemoryAnalyzer.exe工具打开 3,根据工具生成的饼状图可以清晰的找出内存泄漏源
java内存泄漏分析工具
java内存泄露问题的定位与详细的分析过程
几点Java问题,是电子书籍,讲解了Java的内存的问题
NULL 博文链接:https://javaprimary.iteye.com/blog/2286161
java 内存泄漏
由于在开发和面试中往往都会遇到java内存泄露问题,所以综合个人平时遇到的和搜集了些网上的关于内存泄露问题写了这篇总结,同时加了点小例子,希望对大家有所帮组,如果有所不全,希望给我留言提出来,供大家相互...
java内存分析
有关java内存泄露的详细资料,Java与C语言的内存管理模型,内存泄漏方式
详细介绍了 java内存泄露 的一些细节,很受用的
什么是内存泄漏?造成内存泄漏的原因?如何解决内存泄漏?以及如何避免内存泄漏等。。。
内存泄漏问题\防范JAVA内存泄漏解决方案
java内存泄露查询的几个命令系统命令的使用说明
Java内存泄露及内存无法回收解决方案,深入讲解相关原理及相关过程。
本文档通过简单的一些示例,分析了容易引起内存泄露的几大原因,并提出了解决的办法!
java内存泄露定位与分析