文档章节

[翻译]内存泄露简介

nice_so
 nice_so
发布于 2014/01/02 15:45
字数 779
阅读 189
收藏 17

1. 什么是内存泄露?

内存泄露: 对象不再被使用,但是又有引用指向它,所以不能被GC回收。

为了更清楚的理解这个定义,我们需要知道对象在内存中的状态。下面这个插图将对象分为两种状态,被引用的和未被引用的。其中被引用的对象中有一部分是没被使用的。内存泄露就发生在这些对象所在的内存区域。

where-is-memory-leak


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

让我们来看接下来这个例子,它会告诉我们为什么会发生内存泄露。在这个例子中,对象A指向对象B。对象A的生命周期是(t1-t4)比对象B的生命周期(t2-t3)长很多。当对象B不再被程序所使用的时候,对象A依然指向它。这样的话GC就不能从内存中回收对象B。这样的话就可能会引起内存溢出。因为如果对象A指向很多个这样的对象,内存中就会存在很多不能被回收内存空间的对象。

还有另外一种情况,B指向了其它的很多对象,导致了其它的对象也不能被回收。

object-life-time

3.怎样预防内存泄露?

以下有几点预防内存泄露的小建议:

  1. 留心使用集合类,如:HashMap,ArrayList,因为内存泄露通常是它们引起的。当它们被声明为 static,它们的生命周期就跟应用的生命周期相同。

  2. 留心使用事件监听和回调函数。如果监听被注册了之后但是该类不再被使用的时候没有注销也会引起内存泄露。

  3. 成员变量如果是对象的话,需要使用null来销毁这个对象的引用。

4. 为什么JDK6中的substring()方法会导致内存泄露?

JDK6中subString()的源码

//JDK 6
String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
} 
public String substring(int beginIndex, int endIndex) {
    //check boundary
    return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

实际上substring并没有去new 一个String对象,substring返回的字符串和之前的字符串是共用的一个字符数组。

只是数组的起点和长度改变了。所以之前的那个被截取的字符串就没有(也不能)被回收。

如果你想要让它能被回收,可以这样substring.

x.substring(a,b)+""
//or
new String(x.substring(a,b))

前者等同于:

StringBuilder sb = new StringBuilder();
sb.append(x.substring(x, y));
sb.append("");
x = sb.toString();

所以,使用new String(x.substring(a,b))的方式效率更高。


原文:http://www.programcreek.com/2013/10/the-introduction-of-memory-leak-what-why-and-how/


© 著作权归作者所有

共有 人打赏支持
nice_so
粉丝 7
博文 10
码字总数 5904
作品 0
成都
程序员
Android中如何查找内存泄露

1、首先确定是否有内存泄露及哪个程序造成。 1.1、内存泄露已弹出out of memory对话框的情况。 这种情况很简单,直接看对话框就知道是哪个应用的问题了。然后再分析该应用是否是因为内存泄露...

chengche
2013/11/27
0
0
Android性能优化:关于 内存泄露 的知识都在这里了!

前言 在中,内存泄露的现象十分常见;而内存泄露导致的后果会使得应用 本文 全面介绍了内存泄露的本质、原因 & 解决方案,最终提供一些常见的内存泄露分析工具,希望你们会喜欢。 目录 } Li...

Carson_Ho
04/19
0
0
iOS开发 使用Xcode自带的Leaks:动态的检测内存泄露

关于iOS的动态内存检测,Xcode自带了工具(instruments):Leaks。神马,你不知道这个单词是什么意思?google一下,翻译过来意思是“泄露”。 使用方法:点击Product->Profile,然后选择那个...

神补刀
2015/08/12
0
0
解码OutOfMemoryError:PermGen Space

本文由 ImportNew - Peter Pan 翻译自 javacodegeeks。如需转载本文,请先参见文章末尾处的转载要求。 ImportNew注:如果你也对Java技术翻译分享感兴趣,欢迎加入我们的 Java开发 小组。参与...

longbadx
2013/12/27
0
0
Android性能优化:手把手带你全面实现内存优化

前言 在 Android开发中,性能优化策略十分重要 本文主要讲解性能优化中的内存优化,希望你们会喜欢 目录 1. 定义 优化处理 应用程序的内存使用、空间占用 2. 作用 避免因不正确使用内存 & 缺...

codeGoogle
05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot 上传图片(多张和单张都可以)

@RequestMapping("/upload") @ResponseBody public String handleFileUpload(HttpServletRequest request) { MultipartHttpServletRequest params = ((MultipartHttpServletRequest) request......

MrBoyce
1分钟前
0
0
Android Studio 3.X打开DDMS

Android Studio更新到3.0版本以后Tools菜单变成了这样了 DDMS入口找不到了 在设置里找到SDK的路径 打开tools文件夹 双击打开 monitor.bat文件 会出来一个黑色命令行框,稍等一下,熟悉的DDM...

lanyu96
6分钟前
0
0
js 进一法、四舍五入法、舍去法 保留两位小数

function format_number(num,len) { len = len > 0 && len <= 20 ? len : 2; var result = parseFloat(num); num=isNaN(result)?0:result; var numpow=Math.pow(10,len)......

xiaogg
13分钟前
0
0
Node.js中的不安全跳转如何防御详解

Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的开源的...

开元中国2015
14分钟前
1
0
国内首个区块链试验区在海南成立

据新华社报道,10月8日,海南自贸区(港)区块链试验区正式在海南生态软件园授牌设立,这也是目前为止国内第一个区块链试验区。 该试验区位于海南生态软件园,与试验区同一天成立还有2家研究...

问题终结者
15分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部