Java内存泄露详解
2016-03-13 13:57
309 查看
Java内存泄漏发生的情况
字数984 阅读849 评论0 喜欢8虽然Java自带垃圾回收机制(GC),程序员不需要手动进行内存管理,但是仍然会出现内存泄漏的情况。尽管如此,Java的自动内存管理,比起C/C++,内存泄漏的情况大大减少了。下面总结下什么情况下会发生Java内存泄漏。
静态集合类
在使用Set、Vector、HashMap等集合类的时候需要特别注意,有可能会发生内存泄漏。当这些集合被定义成静态的时候,由于它们的生命周期跟应用程序一样长,这时候,就有可能会发生内存泄漏,看下面代码:class StaticTest { private static Vector v = new Vector(10); public void init() { for (int i = 1; i < 100; i++) { Object object = new Object(); v.add(object); object = null; } } }
在上面的代码中,循环申请了
Object对象,并添加到
Vector中,然后将对象设置为
null,可是这些对象因为被
Vector引用着,因此并不能被GC回收,因此造成了内存泄漏。因此,要释放这些对象,还需要被它们从
Vector删除,最简单的方法就是将
Vector设置为
null。
集合里的对象属性值被改变
看以下代码:public static void main(String[] args) { Set<Student> set = new HashSet<Student>(); Student s1 = new Student("Jack"); Student s2 = new Student("Mary"); Student s3 = new Student("Eason"); set.add(s1); set.add(s2); set.add(s3); System.out.println(set.size());//3 s2.setName("Jackson"); //修改属性,此时s2元素对应的hashcode值发生改变 set.remove(s2); // remove不掉,造成内存泄漏 set.add(s2); // 添加成功 System.out.println(set.size());//4 }
在这个例子中,由于对象
s2的属性值被改变了,因此不能从
set中删除,所以
set中会一直保持着
s2的引用,不能被回收,造成了内存泄漏。
监听器
在Java中,我们经常会使用到监听器,如对某个控件添加单击监听器addOnClickListener(),但往往释放对象的时候会忘记删除监听器,这就有可能造成内存泄漏。好的方法就是,在释放对象的时候,应该记住释放所有监听器,这就能避免了因为监听器而导致的内存泄漏。
各种连接
Java中的连接包括数据库连接、网络连接和io连接,如果没有显式调用其
close()方法,是不会自动关闭的,这些连接就不能被GC回收而导致内存泄漏。一般情况下,在
try代码块里创建连接,在
finally里释放连接,就能够避免此类内存泄漏。
外部模块的引用
调用外部模块的时候,也应该注意防止内存泄漏。如模块A调用了外部模块B的一个方法,如:public void register(Object o)
这个方法有可能就使得A模块持有传入对象的引用,这时候需要查看B模块是否提供了去除引用的方法,如
unregister()。这种情况容易忽略,而且发生了内存泄漏的话,比较难察觉,应该在编写代码过程中就应该注意此类问题。
单例模式
使用单例模式的时候也有可能导致内存泄漏。因为单例对象初始化后将在JVM的整个生命周期内存在,如果它持有一个外部对象(生命周期比较短)的引用,那么这个外部对象就不能被回收,而导致内存泄漏。如果这个外部对象还持有其它对象的引用,那么内存泄漏会更严重,因此需要特别注意此类情况。这种情况就需要考虑下单例模式的设计会不会有问题,应该怎样保证不会产生内存泄漏问题。
参考
http://blog.chinaunix.net/uid-7374279-id-4494760.html
相关文章推荐
- Java栈的实例-数组和链表两种方法(转)
- Java NIO内存映射---上G大文件处理(转)
- Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)(转)
- Java的I/O演进
- SpringMVC中传入的对象存放在哪里
- java静态代码块/静态属性、构造块、构造方法执行、main方法、普通代码块的顺序
- Java Socket编程详解
- java 命名规范
- Java awt项目开发
- java的多态
- 使用RxJava来改进用户体验
- Java 直接选择排序
- RxJava学习笔记1
- Java反射探索研究(转)
- Echache整合Spring缓存实例讲解(转)
- java运行 第一个helloword!
- Eclipse如何修改Web项目的名称
- 20145305 《Java程序设计》第2周学习总结
- ProGuard Eclipse Android
- Java 数组实现冒泡排序