定义

内存泄漏是申请了内存用完了不释放,内存溢出是申请内存时,没有足够的内存可以使用。
内存泄漏最终会导致内存溢出,也可以说内存泄漏是内存溢出的一种。

引起内存溢出的原因有那些?

  1. 内存中加载的数据量过于庞大,如一次从数据库中取出过多数据。
  2. 集合类中有对对象的引用,使用完未清空,使得JVM不能回收。
  3. 代码中存在死循环或循环产生过多重复的对象实体。
  4. 使用第三方软件中的BUG
  5. 启动参数内存设置的过小

如何解决?

  1. 修改JVM启动参数,直接增加内存。
  2. 检查错误日志,查看溢出前是否有其他异常或者错误。
  3. 对代码进行检查和分析,找出可能发生内存溢出的位置。

    • 检查代码中是否有死循环或递归调用。
    • 检查是否有循环重复产生新对象实体。
    • 检查对数据库查询中,是否有一次获得全部数据的查询。
    • 检查List、Map等集合对象是否是用完未清除。
  4. 使用内存查看工具动态查看内存使用情况。

    • 使用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。
  • 尽量运用对象池技术以提高系统性能。
  • 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

评论




博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

载入天数...载入时分秒... 本站使用 Volantis 作为主题 鲁ICP备-20012065号