java内存泄漏的问题调查和定位
java管理内存
java有个有点就是有个自己的垃圾回收器(Garbage Collention , GC),GC时刻监视着那些被new出来的对象有没有被引用(这个也是拖慢java运行速度的元凶“痛并快乐”),如果没有被引用就会被回收,开始引用了就从回收池里面拿出来(真的像一个勤劳贴心的保姆)。
什么是java内存泄漏
被new出来的对象越来越多,超过了内存管理的容量,就是内存泄漏。
被分配的对象会有意无意的指向一个方法或者一个正在被用的对象,然而这个对象用过之后就在也没有被用,这种对象就不会被GC回收,会游离在内存中(没人管的对象越来越多,那不就是越来越拥挤)
举个例子,开始上代码
1,对象被其他对象引用
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < list.size(); i++) {
Object object = new Object();
list.add(object);
object = null;//把对象创建出来加入到list后在把这个对象设置为空(被手动回收,类似GC的垃圾回收)
}
···
从上面代码看出,我们已经将object这个对象手动回收了,但是并没有,因为list这个对象要引用object,所以尽管每次循环设置为null,这个对象也是一直以null的形式存在于内存中的,除非list这个对象也被回收,object才会被一起回收。
2,集合被改变
public static void main(String[] args)
{
Set<entity> set = new HashSet<entity>();
entity p1 = new entity("张三",20,"黄色");
entity p2 = new entity("李四",30,"黑色");
entity p3 = new entity("王二",40,"白色");
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!
p3.setAge(35);; //修改p3的年龄,此时p3元素对应的hashcode值发生改变
set.remove(p3); //此时remove不掉(实验过程有时候可以remove掉),造成内存泄漏
System.out.println(p3.getAge()+p3.getName());
set.add(p3); //重新添加,添加不成功
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!
for (entity entity : set)
{
System.out.println(entity.getName());
}
}
···
这个根据其他大神举例子自己手打试了一下,不管有没有对entity做改变,有时候可以remove掉,有时候remove不掉,目前来说就是有可能存在内存泄漏的情况
3,单例模式下
还有单例模式下,单例对象有引用外部对象,这个外部对象也不会被GC回收,也会造成内存泄漏(没有正确使用单例模式的情况下)
4,其他情况
在网上还看到有其他情况下的内存泄漏情况,比如工程中的众多监听器会不会及时被GC回收。还有各种网络连接,比如数据库连接(占用是不是内存太小了,可以忽略嘛),网络连接中的socket,io等等都还没有尝试过,后面在请教其他大神或者慢慢发现把
定位和查找
工程中代码量多,如果要找内存泄漏的地方肉眼是很难的,就要借助其他工具了,借助工具就暂时不表了,还没达到这个层面,先个人理解一下
纯个人理解(借助了其他大神的帖子),纯手打
原文链接一:https://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/