1. 什么是内存泄露?
内存泄露: 对象不再被使用,但是又有引用指向它,所以不能被GC回收。
为了更清楚的理解这个定义,我们需要知道对象在内存中的状态。下面这个插图将对象分为两种状态,被引用的和未被引用的。其中被引用的对象中有一部分是没被使用的。内存泄露就发生在这些对象所在的内存区域。
2. 为什么会发生内存泄露?
让我们来看接下来这个例子,它会告诉我们为什么会发生内存泄露。在这个例子中,对象A指向对象B。对象A的生命周期是(t1-t4)比对象B的生命周期(t2-t3)长很多。当对象B不再被程序所使用的时候,对象A依然指向它。这样的话GC就不能从内存中回收对象B。这样的话就可能会引起内存溢出。因为如果对象A指向很多个这样的对象,内存中就会存在很多不能被回收内存空间的对象。
还有另外一种情况,B指向了其它的很多对象,导致了其它的对象也不能被回收。
3.怎样预防内存泄露?
以下有几点预防内存泄露的小建议:
-
留心使用集合类,如:HashMap,ArrayList,因为内存泄露通常是它们引起的。当它们被声明为
static
,它们的生命周期就跟应用的生命周期相同。 -
留心使用事件监听和回调函数。如果监听被注册了之后但是该类不再被使用的时候没有注销也会引起内存泄露。
-
成员变量如果是对象的话,需要使用null来销毁这个对象的引用。
4. 为什么JDK6中的substring()方法会导致内存泄露?
JDK6中subString()的源码
01 |
//JDK 6 |
02 |
String( int offset, int count, char value[]) {
|
03 |
this .value = value;
|
04 |
this .offset = offset;
|
05 |
this .count = count;
|
06 |
} |
07 |
public String substring( int beginIndex, int endIndex) {
|
08 |
//check boundary
|
09 |
return new String(offset + beginIndex, endIndex - beginIndex, value);
|
10 |
} |
实际上substring并没有去new 一个String对象,substring返回的字符串和之前的字符串是共用的一个字符数组。
只是数组的起点和长度改变了。所以之前的那个被截取的字符串就没有(也不能)被回收。
如果你想要让它能被回收,可以这样substring.
1 |
x.substring(a,b)+ ""
|
2 |
//or |
3 |
new String(x.substring(a,b))
|
前者等同于:
1 |
StringBuilder sb = new StringBuilder();
|
2 |
sb.append(x.substring(x, y)); |
3 |
sb.append( "" );
|
4 |
x = sb.toString(); |
所以,使用new String(x.substring(a,b))的方式效率更高。
原文:http://www.programcreek.com/2013/10/the-introduction-of-memory-leak-what-why-and-how/
相关推荐
讲解关于android内存泄露的各种情况
内存泄露简介: 内存泄露指的是程序在申请内存后,无法释放不再使用的内存空间。在Java中,主要是针对堆内存的泄露,因为堆内存是程序员通过`new`关键字动态分配的,使用完毕后需通过`delete`或`System.gc()`进行...
### Linux 内存泄露查找详解 #### 一、引言 在进行Linux C语言编程时,内存管理一直是程序员关注的重点之一。特别是在动态内存分配场景下,如果不妥善处理,很容易出现内存泄露的问题。内存泄露不仅会消耗系统资源...
### 提高Java开发质量之内存泄露 #### 一、引言 随着J2EE应用程序规模的不断增大,软件系统的稳定性成为衡量开发质量的关键指标之一。其中,“内存泄露”是导致应用不稳定的重要因素之一。内存泄露是指程序在申请...
以一个Web小游戏为例,当使用JProbe进行内存检测时,如果存在内存泄漏问题,例如在GameHandler类中的EJBControllerImpl.startGame()方法,JProbe Memory Debugger将通过实时内存监控和引用图分析,找出可能导致内存...
内存泄漏是指应用程序中不再使用的内存没有被及时释放,从而导致应用程序的内存使用量不断增长,最终可能导致应用程序耗尽所有可用内存,甚至导致整个系统运行缓慢或崩溃。 在Android平台上,由于Java虚拟机的垃圾...
### JVisualVM简介 JVisualVM是Java平台的一个强大的可视化工具,它可以帮助开发者监测和调试应用程序的性能问题,特别是那些与内存管理相关的故障。作为NetBeans的一个子项目,JVisualVM自JDK 1.8起就已经被集成到...
## 简介 Visual C++ 提供了内建的内存泄漏检测功能,但是它的功能非常有限。这个内存泄漏检测器是作为 Visual C++ 内建内存泄漏检测器的一个免费替代品而被创建的。以下是 Visual Leak Detector 的一些特点,这些...
本文将详细介绍"HookLogger"这一内存检查工具,以及如何利用它来检测和解决内存泄露问题。 **HookLogger简介** HookLogger是一款专为Symbian系统设计的内存检查工具。它通过挂钩系统级别的内存分配和释放函数,...
一、UMDH工具简介 UMDH全称为User-Mode Dump Heap,它是一个命令行工具,可以从用户模式的进程创建内存转储文件,并分析该文件以获取内存分配和使用的信息。UMDH能够显示每个模块的私有和共享内存使用情况,这对于...
1. **AQTime简介**: AQTime是一个全面的性能分析器,它提供了丰富的调试方案来帮助程序员分析和优化代码。它不仅适用于32位和64位Windows环境,还支持多种编程语言和框架,包括.NET和JAVA。此外,它还能调试...
1. **Windbg简介** Windbg(Windows Debugger)是微软提供的一个开源调试器,它支持对用户模式和内核模式下的应用程序进行调试。这款工具具有丰富的命令集和强大的数据检查功能,能够帮助开发者深入理解程序运行时...
二、JProfiler简介 JProfiler是一款功能全面的Java性能分析器,它提供了丰富的功能,包括内存分析、CPU剖析、线程监控等。其中,内存分析模块是诊断内存泄漏的关键工具,它能够显示对象分配、存活集、内存池状态以及...
最后,"技术培训_02_JAVA开发体系简介.pptx"可能是一个更广泛的Java开发教程,涵盖了内存管理的基础知识。在Java中,垃圾收集机制自动处理不再被引用的对象,但有时开发者需要手动管理一些资源,例如关闭文件流或...
#### 二、BitmapFactory简介 `BitmapFactory`是Android系统提供的用于加载位图图像的一个工具类。它可以通过各种方式(如文件路径、字节数组、输入流等)来解码图片,并返回一个`Bitmap`对象。但是,默认情况下,`...
Purify 在报告内存问题的时候,可以指出源程序中哪个地方出现内存问题,但对于内存泄漏而言,它只能指出出现问题的内存是哪一块,也就是指出内存是在哪里被分配的,而不是指出内存泄露是如何发生的。如果让 Purify ...
简介:虽然用 Java:trade_mark: 语言编写的程序在理论上是不会出现“内存泄漏”的,但是有时对象在不再作为程序的逻辑状态的一部分之后仍然不被垃圾收集。本月,负责保障应用程序健康的工程师 Brian Goetz 探讨了无...