JAVA内存泄露
李海燕 2016/7/18
1.概念
内存泄露(Memory Leak):程序申请内存后,无法释放申请的内存空间,内存泄露最终会导致溢出;
内存溢出:欲申请的内存超出了系统可以给出,抛出内存溢出异常;
2.如何检测
2.1 使用内存映像分析工具(Eclipse Memory Analyzer)对Dump出来的堆转储快照进行分析,确认内存中的对象是不是必要的,如果是必要的那就是发生了溢出,不必要的就是内存泄露了;
2.2 使用jps获取线程ID,然后打开Jconsole id;观察内存使用情况即可;
3.溢出原因
根本原因:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。
说明:对于数组的操作,堆和栈的操作要慎重的考虑泄露问题(出栈的时候没有清理掉最后一个元素即没有对最后一个元素置空);
4.举例说明
4.1 使用HashMap不当
说明:HashMap里面添加元素,如果key没有实现hashCode()和equals()方法,这样相同的对象会重复加入HashMap中,GC也不会回收的;
比如代码中出现:while(true){hashmap.put(new Key(“kk”),”ll”)}那么一直执行,最后会导致OutOfMemory异常;
4.2 大量使用String
说明:比如需要拼接字符串时候,如果使用String类,那就会生成大量的中间对象,放置在常量池中,GC主要针对堆进行回收,运行时常量池属于永久代,永久代中回收主要针对:常量池的回收和类型的卸载比较严格。容易造成一段时间的内存泄露。
4.3 监听器
在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。
比如Java中观察者模式实现是通过继承Observable类的对象:调用setChanged()方法和notifyObservers()通知监听对象执行update()方法;同时监听对象必须实现Observer接口的update(Observable obserale,Object args)方法,因此监听器构造方法(this引用逃逸)必须指定或者提供一个方法指定Observable对象,然后调用给对象的addObserver(this)方法,就OK了;
4.4 各种连接
如数据库连接(dataSource.getConnection())、网络连接(socket)和IO连接必须显示的关闭连接,否则GC不会回收这些对象的,一般在try里面去连接,最后在finally里面close();
4.4 内部类引用
内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法如:
public void registerMsg(Object b);
这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。
4.5 单例模式
比如一个单例模式内部引用了一个对象,我们知道单例模式的话以静态变量形式存在整个生命周期里面,所以会一直持有对那个对象的引用,假想那个对象是一个很大的数组或者集合,本来那个对象生命周期到了,可却因为单例模式的引用导致不能回收;
观察假如我们在一个Activity A中使用了Util类:Util.getInstance(this),那么这个A对象一定不能释放;
public class Util {
private Context mContext;
private static Util instance=null;
private Util(Context context){
this.mContext = context;
}
public static Util getInstance(Context context){
if(instace==null){
synchronized(Util.class){
if(instance==null)instance=new Util(context);
}
}
return instance;
}
}
4.6 session
如果服务器session失效时间(timeout)设置的太长,会引发内存泄露问题;
分享到:
相关推荐
### Java避免内存泄露的关键知识点 #### 一、内存泄露的概念及原因 内存泄露是指程序在申请内存后未能释放,导致这部分内存无法再次被利用。在Java中,由于具备垃圾回收机制(GC),理论上开发者不必担心内存泄露...
Java内存泄漏问题处理方法经验总结是Java开发中非常重要的一个方面,今天我们将分享关于Java内存泄漏问题处理方法经验总结的知识点。 首先,Java内存泄漏的问题描述是系统在某个时间点突然发生内存溢出问题,日志...
本文将基于“性能测试 内存泄漏的检测、定位和解决经验总结”这一主题,深入探讨相关知识点。 首先,理解什么是内存泄漏至关重要。内存泄漏是指程序在申请内存后,无法释放已不再使用的内存空间,一次小的内存泄漏...
这本书详细探讨了Java内存模型(JVM)的基础知识,以及如何利用这些知识来提升程序的效率和稳定性。以下是该书可能涵盖的一些关键知识点: 1. **Java内存模型基础**:首先,书中会介绍Java内存模型的架构,包括堆...
2. **内存管理**:Java自动进行垃圾回收(Garbage Collection),程序员无需手动释放内存,降低了内存泄漏的风险。 3. **异常处理**:Java强制使用try-catch-finally语句块处理异常,增强了程序的健壮性。 **三、...
**JAVA基础知识精华总结** 在Java编程领域,基础...这份"JAVA基础知识精华总结"文档详细涵盖了这些关键知识点,是Java学习者的重要参考资料。无论是初学者还是有经验的开发者,都可以从中受益,提升自己的编程技能。
特别地,Java虚拟机(JVM)管理内存的方式使得开发者需要了解一些基本的内存占用知识,以便在进行内存优化和避免内存溢出时能够做出更合理的决策。 首先,文档指出了Java中基本数据类型和对象在内存中的占用大小。在...
3. **性能优化**:Java程序员可能会分享他们在优化代码性能、减少内存泄漏、提高并发处理能力等方面的技巧和案例。 4. **微服务架构**:随着微服务的流行,总结可能包含如何设计和实现微服务架构,以及在这一过程中...
总的来说,《JAVA内存调优白皮书(IBM)》是Java开发者进行性能优化的重要参考资料,它帮助我们理解JVM内存的工作机制,掌握调优技巧,以提升应用的运行效率和用户体验。通过深入学习和实践,开发者可以更好地应对复杂...
尽管给定的部分内容主要涉及网站的版权声明和重复的下载指引,并未直接提供具体的Java知识点,但从标题“Java参考大全”和描述“Java参考大全,自己下载的分享给大家”可以推测,这份资料可能涵盖广泛的Java基础知识...
本文将基于给定的信息,深入探讨Android内存泄露测试的关键知识点。 #### 一、内存泄露的原因与检测工具 内存泄露可能由多种原因引起,包括但不限于对象引用未正确管理、静态集合的过度使用、Handler和Runnable的...
7. **CHAP17.LST**:可能涉及Java的内存管理和性能优化,如垃圾收集器的工作原理,内存泄漏的检测与防止,以及如何通过JVM参数调优提升程序性能。 8. **CHAP8.LST**:这部分可能涵盖异常处理机制,包括异常分类、...
4. **垃圾收集机制**:Java自动进行内存管理,垃圾收集器负责回收不再使用的对象所占用的内存,防止内存泄漏。 5. **反射(Reflection)**:Java反射机制允许在运行时检查类的信息,创建和操作类的对象,这对于动态...
本资源集合了Java程序员应该了解的关键知识点,并提供了一些知名公司的面试题目,旨在帮助初学者巩固基础,同时为有经验的程序员提供复习材料。 首先,让我们探讨Java的基础知识。Java是一种面向对象的语言,它的三...
Java架构知识库整理PDF版是一份详尽的资源,涵盖了Java开发和架构设计的各个方面,旨在为Java学习者提供一个全面的学习指南。这份文档可能包含了从基础语法、面向对象编程概念,到高级并发处理、内存管理、性能优化...
以下是根据提供的题目解析总结的一些关键知识点: 1. **Java语言特点**: - 面向对象:Java是一种面向对象的语言,支持类、接口和继承等面向对象特性。 - 分布式:Java支持网络分布式计算,如RMI(远程方法调用)...
垃圾回收机制是Java的一大特色,它自动管理内存,避免了C++等语言中的内存泄漏问题。多线程使得Java程序能够同时执行多个任务,提高了效率。集合框架是Java提供的数据结构和算法的集合,包括ArrayList、LinkedList、...