翻译练习-你应该知道关于内存泄漏的所有事情

原文:https://proandroiddev.com/everything-you-need-to-know-about-memory-leaks-in-android-d7a59faaf46a

Java语言的一个核心优势,或者更精确一点,这个JVM虚拟机的核心优势,是垃圾回收器,它可以让我们创建新的对象而不需要担心它的内存释放,它将负责释放内存.

我们也可以阻碍垃圾回收器去释放内存,如果我们不了解GC(垃圾回收器)的工作机制。

如果没有对gc工作原理搞懂,将会写出内存泄漏的代码,内存泄漏将会浪费app的内存,从而导致卡顿和内存溢出异常.

什么是内存泄漏

从内存中去释放不会使用的对象失败,就是内存泄漏
释放不会使用的对象失败意味着GC不能清理内存掉那些内存,如果GC不能清理掉我们就会有麻烦了,这块没有使用的对象将会占据内存空间一直到应用程序结束,或者某个方法结束.
直到方法结束?是的。我们有两种内存泄漏的情况,一种是一直占用内存空间直到应用程序结束,另外一种是占据内存空间到方法结束。前者应该容易明白,后者需要说明一下,让我来举个例子去描述这种情况,假设我们有方法X,方法X在后台做一个长时间的任务,它1分钟后才结束,方法X引用到了一个未使用的对象,在这种情况下,这种情况下未使用的对象内存将会占据,这一分钟内未使用的对象内存将不会释放,直到这个后台任务结束,GC才能清理掉它的内存.

一些基础

什么是内存
内存,或者随机访问内存,是一个在安卓设备或者计算机中用于存储当前运行应用的数据.
我打算去描述下在内存中两个主要的角色,堆和栈。


image.png

我不打算做太长的阐述,来说下关键点,一个简单描述,栈用来静态内存的分配而堆用来做动态内存的分配。要记住堆和栈都是存放在内存中的。

Java堆内存被用来虚拟机分配对象使用。无论什么时候创建对象,它始终在堆创建,虚拟机,像JVM 和 DVM,运行规则的GC,释放掉没有引用的对象.
为了提供更好的用户体验,Android对于每个应用程序有一个限制的堆大小,这个限制的堆大小在不同大小ram手机上不同,如果你的app超过这个大小,将会抛出OutOfMemoryError然后被终止.

你曾经对应用程序的堆大小好奇吗?

我们来看看它们是多大,应用程序运行在DVM上,DVM是Java虚拟机针对移动设备的优化版本,它优化了虚拟机的内存,电池消耗,还有性能,它负责对每个应用程序分配内存.
来说下DVM中的两行参数:
dalvik.vm.heapgrowthlimit:
应用程序刚开始的堆内存大小,它是默认的堆内存大小,也是你应用最大的内存大小。
dalvik.vm.heapsize:
这是一个更大的堆内存大小,你可以在应用manifest中声明android:largeHeap=”true”获取。
通常不要使用这个参数获取更大的内存,除非你知道这个操作的副作用。
下面这个表格描述了不同ram设备应用程序的内存大小.


image.png

记住更大的ram你将会有更高的应用内存,

如何产看应用中分配的内存大小

通过ActivityManager的getMemoryClass()和getLargeMemoryClass()将分别获得,默认的堆内存大小,和最大的堆内存大小.

真实的代码怎么分配内存

下面简单的案例来说明怎么分配内存


image.png

下面的图展示了应用程序启动后,堆栈内存的分配情况


image.png

我们将会回顾应用的执行和停止,描述什么时候分配对象,在堆栈中存储,我们也会看堆栈释放内存的情况.
image.png

行1 :JVM创建一个栈内存块对于main方法.


image.png

行2 :在这一行中,我们创建了原始本地变量,这个变量将会被创建存放main方法栈内存中
image.png

行3 :这里我需要你注意,在这行中,我们创建了一个新的对象,这个对象在main方法的栈中被创建,然后存储在堆中,栈存放了该对象的引用,就是堆中该对象的地址,堆中存储了原始对象.
image.png

行4 :和行3是一样的.

image.png

行5 :JVM为foo方法创建一个栈内存块

image.png

行6 :创建一个新的对象,这个对象被创建在foo方法的栈内存中,它存放一个地址指向堆中第三行创建的对象。这个第三行创建的对象在堆中的地址我们通过行5传递过来,始终记住java始终传递的是引用.


image.png

行7 :我们将创建一个新的对象,这个对象被创建在栈中,然后指到堆的string pool中


image.png

行8 :foo方法的最后一行,栈中存储foo方法块将会被释放调
image.png

行9 :和行8是一样的main方法结束,栈中存储main方法块将会被释放调

方法结束后相应的栈内存被释放掉

image.png

该图表示了foo方法终止后,foo方法的栈内存将会被释放和回收

image.png

这是相同的,当main方法结束掉后,main方法的栈内存将会被释放和回收

结论:
现在,栈内存中的对象是临时的,一旦方法终止,对象将会被释放和回收。
栈是一个LIFO数据结构 (Last-In-First-Out),你可以把它看成一个盒子,通过这种结构,程序可以简单的管理通过push和pop.


image.png

每次你需要去存储像一个变量或者方法它会push进去,然后栈针上移,从方法中退出,pop操作后,栈针指向的内存下移。

堆内存的释放

与栈不同的是,释放和回收来自堆的对象,我们需要帮助。
对于Java,或者更精确点来说,这个Jvm有一个超级英雄的角色帮助我们。我们称它为垃圾回收器。它会为我们努力工作。发现未使用的对象,释放它们,然后省出更多的内存.

垃圾回收器如何释放堆内存
垃圾回收器将会回收掉没有引用的对象,当这里一个对象在堆没有任何引用到它,垃圾回收器将会释放它,开拓更多的空间。


image.png

GC root是JVM引用到的对象。它是这棵树的初始对象。每个对象都会有一个或者更多root对象。只要应用或者GC roots可以引用那些roots或者那些对象,整个数是可获得的。一旦它们没有被application或者GC获取到,将认为它们是不能获取的对象(无用的对象).

垃圾回收器触发后将会发生什么?
对于现在,当前内存中栈的状态被清空了,堆充满了未使用的对象.


image.png

在运行GC后将会变成


image.png

GC将会释放和清除所有未使用的对象从堆中。

内存泄漏是如何导致的

内存泄漏当栈中仍然引用了在堆中未使用的对象。详情见下图


image.png

从图中我们可以看到一些无用对象仍然有引用。垃圾回收器回收不到它们。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容