什么是内存泄漏(转载自ImportNew)

本文由 ImportNew - 范琦琦 翻译自 Programcreek。欢迎加入翻译小组。转载请见文末要求。

Java最显著的优势之一就是它的内存管理机制。你只需简单创建对象,然后Java垃圾回收机制便会小心的分配和释放内存。然而,事实并非如此简单,因为在Java应用程序中经常发生内存泄漏。

本教程说明了什么是内存泄漏,为什么会发生,以及如何防止它们。

1.什么是内存泄漏?

内存泄漏的定义: 对象不再被应用程序使用,但是垃圾回收器却不能移除它们,因为它们正在被引用。

要理解这个定义,我们需要理解对象在内存中的状态,下图说明了哪些是未被使用的以及哪些是未被引用的。


从图中可以看到被引用的对象和未被引用的对象。未被引用的对象将会被垃圾回收器回收,而被引用对象则不会被回收。未被引用的对象理所当然是未被使用的,因为没有其他的对象引用它。然而,未被使用的对象并不一定是未被引用的,其中一些是被引用的。这就是内存泄漏的起因。

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

让我们来看看下面这个例子,看看为什么内存泄漏会发生。在如下例子中,对象A引用了对象B。A的生命周期(t1—t4)要比B的生命周期(t2—t3)长很多。当B不再用于应用中时,A仍然持有对它的引用。在这种方式下,垃圾回收器就不能将B从内存中移除。这将可能导致出现内存不足的问题,因为如果A对更多的对象做同样的事情,那么内存中将会有很多无法被回收的对象,这将极度耗费内存空间。

也有可能B持有大量对其他对象的引用,这些被B引用的对象也不能够被回收。所有这些未被使用的对象将会耗费宝贵的内存空间。


3.如何阻止内存泄漏?

以下是一些阻止内存泄漏的快速动手技巧。

(1)注意集合类,例如HashMap,ArrayList,等等。因为它们是内存泄漏经常发生的地方。当它们被声明为静态时,它们的生命周期就同应用程序的生命周期一般长。

(2)注意事件监听器和回调,如果一个监听器已经注册,但是当这个类不再被使用时却未被注销,就会发生内存泄漏。

(3)“如果一个类管理它自己的内存,程序员应该对内存泄漏保持警惕。”[1] 很多时候当一个对象的成员变量指向其他对象时,不再使用时需要被置为null。

4.一个小测验:为什么在JDK6中substring()方法会引起内存泄漏?

为了回答这个问题,您可能需要阅读JDK6和7中的substring()

参考文献:
[1]Bloch,Joshua.Effective Java.Addison-Wesley Professional, 2008
[2]IBM Developer Work.http://www.ibm.com/developerworks/library/j-leaks/

原文链接: Programcreek 翻译: ImportNew.com范琦琦
译文链接: http://www.importnew.com/8715.html
转载请保留原文出处、译者和译文链接。]

关于作者: 范琦琦

原文地址:https://www.cnblogs.com/FANKIKI/p/8457543.html

时间: 2024-10-20 23:44:31

什么是内存泄漏(转载自ImportNew)的相关文章

最快速度找到内存泄漏[转载]

转载链接:http://blog.csdn.net/eric_jo/article/details/4264442 内存管理是C++程序员的痛.我的<内存管理变革系列>就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C++程序员的负担. 这篇短文我想换个方式,讨论一下如何以最快的速度找到内存泄漏. 确认是否存在内存泄漏 我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏.例如: class CMyApp : public CWinApp { p

Java 理论与实践: 用弱引用堵住内存泄漏---转载

要让垃圾收集(GC)回收程序不再使用的对象,对象的逻辑 生命周期(应用程序使用它的时间)和对该对象拥有的引用的实际 生命周期必须是相同的.在大多数时候,好的软件工程技术保证这是自动实现的,不用我们对对象生命周期问题花费过多心思.但是偶尔我们会创建一个引用,它在内存中包含对象的时间比我们预期的要长得多,这种情况称为无意识的对象保留(unintentional object retention). 全局 Map 造成的内存泄漏 无意识对象保留最常见的原因是使用 Map 将元数据与临时对象(trans

关于js闭包是否真的会造成内存泄漏(转载)

闭包是一个非常强大的特性,但人们对其也有诸多无解.一种危言耸听的说法是闭包会造成内存泄露. 局部变量本来应该在函数退出的时候被解除引用,但如果局部变量被封闭在闭包形成的环境中,那么这个局部变量就能一直生存下去.从这个意义上看,闭包的确会使一些数据无法被及时销毁.使用闭包的一部分原因是我们选择主动把一些变量封存在闭包中,因为可能在以后还需要使用这些变量,把这些变量放在闭包中和放在全局作用域,对内存方面的影响是一致的,这里并不能说成是内存泄露.如果在将来需要回收这些变量,我们可以手动把这些变量设为n

Java 内存泄漏--全解析和处理办法 [ 转载 ]

Java内存泄露——全解析和处理办法 [转载] @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a 本文章会一步一步的探讨内存泄露的问题.博主第一次书写长篇技术贴,如有错误或不周到的地方请多指教. JAVA是垃圾回收语言的一种,开发者无需特意管理内存分配.但是JAVA中还是存在着许多内存泄露的可能性,如果不好好处理内存泄露,会导致APP内存单元无法释放被浪费掉,最终导致内存全部占据堆栈(heap)挤爆进而程序崩溃. 内存泄露 说到

【转载】gdi+ 内存泄漏

[转载]http://issf.blog.163.com/blog/static/1941290822009111894413472/ 最近用GDI+实现了几个自定义控件,但是发现存在内存泄露问题 BOOL CGdiplusBugDlg::OnEraseBkgnd(CDC* pDC) {Image* pImage = Image::FromFile(L"E:\\bac.bmp");Graphics g(pDC->m_hDC); g.DrawImage(pImage,0,0); r

VS2005内存泄漏检测方法[转载]

一.非MFC程序可以用以下方法检测内存泄露: 1. 程序开始包含如下定义: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK #endif   // _DEBUG #define _CRTDBG_MAP_ALLOC #include #include #ifdef _DEBUG #define new   DEBUG_CLI

(转载)IOS- Instruments使用之使用Leaks检测内存泄漏

转载 :http://www.zhimengzhe.com/IOSkaifa/255950.html 上一篇文章我介绍了Instruments的工具分类和基本使用方法,今天我再来给大家说说Leaks的使用方法. 在早期的iOS开发中,并没有ARC模式,只有MRC模式,必须由开发人员自己管理内存,过程非常繁琐而且容易造成内存泄漏,如今的iOS开发虽然基本都是用的ARC模式,但是有些情况下还是需要我们自己来管理内存,稍有不慎,就可能造成内存泄漏,所以,使用一款内存泄漏的检测工具还是非常有必要的. 接

Java的内存泄漏_与C/C++对比(转载总结)

原文网址:http://developer.51cto.com/art/201111/302465.htm Java内存泄露的理解与解决(1) 一般来说内存泄漏有两种情况.一种情况如在C/C++ 语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值):另一种情况则是在内存对象已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用).第一种情况,在 Java 中已经由于垃圾回收机制的引入,得到了很好的解决.所以, Java 中的内存泄漏,主要

VS2005 检测内存泄漏的方法(转载)

一.非MFC程序可以用以下方法检测内存泄露: 1.程序开始包含如下定义: [cpp] view plain copy print? #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK #endif  // _DEBUG #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #includ