Java语言的一个关键的优势就是它的内存管理机制。你只管创建对象,Java的垃圾回收器帮你分配以及回收内存。然而,实际的情况并没有那么简单,因为内存泄漏在Java应用程序中还是时有发生的。

  下面就解释下什么是内存泄漏,它为什么会发生,以及我们如何阻止它的发生。

 1. 什么是内存泄漏?

  内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着。

  要想理解这个定义,我们需要先了解一下对象在内存中的状态。下面的这张图就解释了什么是无用对象以及什么是未被引用对象。

Unused and Unreferenced

  上面图中可以看出,里面有被引用对象和未被引用对象。未被引用对象会被垃圾回收器回收,而被引用的对象却不会。未被引用的对象当然是不再被使用的对象,因为没有对象再引用它。然而无用对象却不全是未被引用对象。其中还有被引用的。就是这种情况导致了内存泄漏。

 2. 为什么会发生内存泄漏?

  来先看看下面的例子,为什么会发生内存泄漏。下面这个例子中,A对象引用B对象,A对象的生命周期(t1-t4)比B对象的生命周期(t2-t3)长的多。当B对象没有被应用程序使用之后,A对象仍然在引用着B对象。这样,垃圾回收器就没办法将B对象从内存中移除,从而导致内存问题,因为如果A引用更多这样的对象,那将有更多的未被引用对象存在,并消耗内存空间。

  B对象也可能会持有许多其他的对象,那这些对象同样也不会被垃圾回收器回收。所有这些没在使用的对象将持续的消耗之前分配的内存空间。

Object-Life-Time

 3. 如何防止内存泄漏的发生?

  下面是几条容易上手的建议,来帮助你防止内存泄漏的发生。

  • 特别注意一些像HashMap、ArrayList的集合对象,它们经常会引发内存泄漏。当它们被声明为static时,它们的生命周期就会和应用程序一样长。
  • 特别注意事件监听和回调函数。当一个监听器在使用的时候被注册,但不再使用之后却未被反注册。
  • “如果一个类自己管理内存,那开发人员就得小心内存泄漏问题了。” 通常一些成员变量引用其他对象,初始化的时候需要置空。

 4. 一个小问题:为什么JDK6中的substirng()方法容易导致内存泄漏?

  要想解答上面的问题,你或许可以看看Substring() in JDK 6 and 7

  外文链接:The Introduction of Java Memory Leaks

最新文章

  1. Mybatis环境
  2. 仅此一文让你明白ASP.NET MVC 之Model的呈现(仅此一文系列三)
  3. TOMCAT开放远程调试端口
  4. asp.net core 使用EF7 Code First 创建数据库,同时使用命令创建数据库
  5. C# 只启动一个实例完全解决方案
  6. Net数值计算MathNet.Numerics类库
  7. SD卡中的命令CMD
  8. windows内存映射学习及帮助类实现
  9. Poj 1006 / OpenJudge 2977 1006 Biorhythms/生理周期
  10. margin设置为负数
  11. Sublime Text 皮肤插件安装
  12. 并发编程实践三:Condition
  13. pthread_create线程创建的过程剖析(转)
  14. iOS 之 内嵌网页
  15. Servlet中编码在过滤器中的使用
  16. 在shell脚本中使用alias
  17. 深入理解 react-router 路由系统
  18. Python_@修饰器(装饰器)的理解
  19. 【dfs】P1433 吃奶酪
  20. djiango 虚拟环境与项目创建

热门文章

  1. metasploit 读书笔记1
  2. tensorboard的安装及遇到的问题
  3. 2019-RHCE-红帽题库(稳定)
  4. plsql查询结果中文乱码
  5. web flash推流h264视频取消cbr
  6. P4177 [CEOI2008]order 最小割
  7. P1979 华容道
  8. php 伪造HTTP_REFERER页面URL来源的三种方法
  9. C语言初步学习I/O函数scanf、getchar、printf和putchar
  10. C#学习之按钮点击事件