文档章节

[翻译]内存泄露简介

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

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

Android性能优化:关于 内存泄露 的知识都在这里了!

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

Carson_Ho ⋅ 04/19 ⋅ 0

解码OutOfMemoryError:PermGen Space

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

longbadx ⋅ 2013/12/27 ⋅ 0

iOS开发 使用Xcode自带的Leaks:动态的检测内存泄露

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

神补刀 ⋅ 2015/08/12 ⋅ 0

Android性能优化:手把手带你全面实现内存优化

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

codeGoogle ⋅ 05/08 ⋅ 0

Android内存泄漏简介

不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露。其实如果我们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无...

Jerikc ⋅ 2013/08/14 ⋅ 4

Windows平台下如何检测C/C++内存泄露?

对于C/C++程序员来说,效率和优雅性大多数情况是对立的,我们经常会在这里面抉择,到底应该怎么取舍。而说到效率,就不得不说让这类程序员头疼了N年的问题,内存泄露,至少从C/C++发明以来很...

lolicone ⋅ 2012/10/28 ⋅ 0

1. 垃圾收集简介 - GC参考手册

说明: 在本文中, 翻译为 “”, 翻译为 “”; 一般认为, 垃圾回收 和 垃圾收集 是同义词。 翻译为: 小型GC; 而不是 次要GC 翻译为: 大型GC; 而不是 主要GC 原因在于,大部分情况下, 发生在年...

renfufei ⋅ 2016/12/02 ⋅ 0

LeakCanary——消除Android中的内存泄露

LeakCanary 简介 LeakCanary是Square公司最近公布的开源项目,旨在消除Android中的内存泄露(Memory Leak),项目地址猛戳这里。 使用 LeakCanary的使用也非常之简单,仅需要在Application中...

iuKa ⋅ 2015/05/11 ⋅ 0

iOS 理解引用计数

一 简介 OC 语言使用引用计数来管理内存每个对象都有个可以递增或递减的计数器,如果想某个对象继续存活,那就递增其引用计数,用完之后,就递减其计数,计数变为0,就销毁。 二 引用计数工作...

卧龙小 ⋅ 2015/08/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring Email

使用spring发Email其实就是使用spring自己封装携带的一个javamail.JavaMailSenderImpl类而已。这个类可以当一个普通的java对象来使用,也可以通过把它配置变成spring Bean的方式然后注入使用...

BobwithB ⋅ 21分钟前 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 24分钟前 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 25分钟前 ⋅ 0

IT行业的变革就像世界杯德国对战墨西哥一样难以预测[图]

最近在观看世界杯,尤其是昨天的比赛,上一届卫冕冠军德国队居然0:1告负墨西哥,这创造了历史,首先是墨西哥从来没赢过德国队,其次是德国队36年来首站没输过,再差也是打平,而这次,德国队...

原创小博客 ⋅ 44分钟前 ⋅ 0

解决CentOS6、7,/etc/sysconfig/下没有iptables的问题

一、Centos 6版本解决办法: 1.任意运行一条iptables防火墙规则配置命令: iptables -P OUTPUT ACCEPT 2.对iptables服务进行保存: service iptables save 3.重启iptables服务: service ...

寰宇01 ⋅ 54分钟前 ⋅ 2

数据库备份和恢复

备份:mysqldump -u root -p 数据库>磁盘路径 恢复:mysql -u root -p 数据库<sql脚本的磁盘路径

anlve ⋅ 今天 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部