定义
内存泄漏是申请了内存用完了不释放,内存溢出是申请内存时,没有足够的内存可以使用。
内存泄漏最终会导致内存溢出,也可以说内存泄漏是内存溢出的一种。
引起内存溢出的原因有那些?
- 内存中加载的数据量过于庞大,如一次从数据库中取出过多数据。
- 集合类中有对对象的引用,使用完未清空,使得JVM不能回收。
- 代码中存在死循环或循环产生过多重复的对象实体。
- 使用第三方软件中的BUG
- 启动参数内存设置的过小
如何解决?
- 修改JVM启动参数,直接增加内存。
- 检查错误日志,查看溢出前是否有其他异常或者错误。
对代码进行检查和分析,找出可能发生内存溢出的位置。
- 检查代码中是否有死循环或递归调用。
- 检查是否有循环重复产生新对象实体。
- 检查对数据库查询中,是否有一次获得全部数据的查询。
- 检查List、Map等集合对象是否是用完未清除。
使用内存查看工具动态查看内存使用情况。
- 使用
jmap命令。 jmap pid查看共享对象信息。jmap -head pid查看堆使用情况jmap -histo pid查看堆中对象数量和大小jmap -dump:fromat=b,file=heapdump pid将内存使用的详细情况输出到文件。然后可以使用jhat -port 4000 filename查看该文件。
- 使用jvisualvm、jconsole等JVM可视化工具。
- 使用
注意事项
内存溢出绝大部分时候都是源码层面的问题,在开发过程中需要注意:
- 尽早释放无用对象的引用
- 程序里不可避免大量使用字符串时,避免使用String,应使用StringBuffer。
- 尽量减少静态变量的使用,静态变量是全局的,GC不会回收。
- 避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时容易触发GC。
- 尽量运用对象池技术以提高系统性能。
- 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。