文档章节

[翻译]内存泄露简介

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
解码OutOfMemoryError:PermGen Space

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

longbadx
2013/12/27
0
0
iOS开发 使用Xcode自带的Leaks:动态的检测内存泄露

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

神补刀
2015/08/12
0
0
Android性能优化:手把手带你全面实现内存优化

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

codeGoogle
05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

49.Nginx防盗链 访问控制 解析php相关 代理服务器

12.13 Nginx防盗链 12.14 Nginx访问控制 12.15 Nginx解析php相关配置(502的问题) 12.16 Nginx代理 扩展 502问题汇总 http://ask.apelearn.com/question/9109 location优先级 http://blog....

王鑫linux
今天
1
0
Nginx防盗链、访问控制、解析php相关配置、Nginx代理

一、Nginx防盗链 1. 编辑虚拟主机配置文件 vim /usr/local/nginx/conf/vhost/test.com.conf 2. 在配置文件中添加如下的内容 { expires 7d; valid_referers none blocked server_names *.tes......

芬野de博客
今天
0
0
spring EL 和资源调用

资源调用 import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.PropertySource;import org.springframework.core.io.Resource;......

Canaan_
今天
1
0
memcached命令行、memcached数据导出和导入

一、memcached命令行 yum装telnet yum install telent 进入memcached telnet 127.0.0.1 11211 命令最后的2表示,两位字节,30表示过期时间(秒) 查看key1 get key1 删除:ctrl+删除键 二、m...

Zhouliang6
今天
1
0
Linux定时备份MySQL数据库

做项目有时候要备份数据库,手动备份太麻烦,所以找了一下定时备份数据库的方法 Linux里有一个 crontab 命令被用来提交和管理用户的需要周期性执行的任务,就像Windows里的定时任务一样,用这...

月夜中徘徊
今天
1
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部