android 内存泄漏

相信大部分童靴都有听说个名词:内存泄漏
究竟什么是内存泄漏,它具体有什么危害呢?且听我娓娓道来

JVM/ART

首先为大家普及下,Java 运行时是有一套虚拟机机制存在的:
JVM(Java 虚拟机)
是一个虚构出来的运行 Java 程序的运行时,是通过在实际的计算机上仿真模拟各种计算机功能的实现。它具有完善的硬件架构(如处理器、堆栈、寄存器等),还具有相应的指令系统,使用 JVM 就是使 Java 程序支持与操作系统无关。理论上在任何操作系统中,只要有对应的 JVM,即可运行 Java 程序。
ART(Android 虚拟机)
是在 Android 系统上运行 Android 程序的虚拟机,其指令集是基于寄存器架构的,执行特有的文件格式-dex 字节码来完成对象生命周期管理、堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能。
其实 ART 就是在 JVM 基础上专门为 Android 移动设备定制的一套虚拟机方案

内存泄漏/内存溢出

内存泄露(Memory leak)
程序在向系统申请分配内存空间后(new),在使用完毕后未释放。结果导致一直占据该内存单元,我们和程序都无法再使用该内存单元,直到程序结束,这是内存泄露。
内存溢出(out of memory)
程序向系统申请的内存空间超出了系统能给的,比如一车最多能坐 5 个人,你却非要塞下 10 个,车就挤爆了。
大量的内存泄露会导致内存溢出(oom)

内存区域

Java 是在 JVM 所虚拟出的内存环境中运行的,JVM 的内存可分为三个区:堆(heap)、栈(stack)和方法区(method)。
栈(stack)
是简单的数据结构,但在计算机中使用广泛。栈最显著的特征是:LIFO(Last In, First Out, 后进先出),栈中只存放基本类型和对象的引用(不是对象)
堆(heap)
堆内存用于存放由 new 创建的对象和数组。在堆中分配的内存,由 Java 虚拟机自动垃圾回收器来管理。JVM 只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
方法区(method)
又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的 class 和 static 变量

内存泄漏原因分析

image.png

那么问题来了?究竟哪部分的内存会导致内存泄漏呢?
在 Java 中 JVM 的栈记录了方法的调用,每个线程拥有一个栈。在线程的运行过程当中,执行到一个新的方法调用,就在栈中增加一个内存单元,即帧(frame)。在 frame 中,保存有该方法调用的参数、局部变量和返回地址。然而 Java 中的局部变量只能是基本类型变量(int),或者对象的引用。所以在栈中只存放基本类型变量和对象的引用。引用的对象保存在堆中
当某方法运行结束时,该方法对应的 frame 将会从栈中删除,frame 中所有局部变量和参数所占有的空间也随之释放。线程回到原方法继续执行,当所有的栈都清空的时候,程序也就随之运行结束。
而对于堆内存,堆存放着普通变量。在 Java 中堆内存不会随着方法的结束而清空,所以在方法中定义了局部变量,在方法结束后变量依然存活在堆中。
综上所述,栈(stack)可以自行清除不用的内存空间。但是如果我们不停的创建新对象,堆(heap)的内存空间就会被消耗尽。所以 Java 引入了垃圾回收(garbage collection,简称 GC)去处理堆内存的回收,但如果对象一直被引用无法被回收,造成内存的浪费,无法再被使用。所以对象无法被 GC 回收就是造成内存泄露的原因!

垃圾回收机制

垃圾回收(garbage collection,简称 GC)可以自动清空堆中不再使用的对象。在 Java 中对象是通过引用使用的。如果再没有引用指向该对象,那么该对象就无从处理或调用该对象,这样的对象称为不可到达(unreachable)。垃圾回收用于释放不可到达的对象所占据的内存。
image.png

根据上图可以知道:由于 obj4 没有 root 指向它,所以 GC 会释放它
obj7 由于还有其他引用指向它,所以得不到释放
如果持有对象的强引用,垃圾回收器是无法在内存中回收这个对象

所以内存泄露的真因是:
持有对象的强引用,且没有及时释放,进而造成内存单元一直被占用,浪费空间,甚至可能造成内存溢出!

内存泄漏对应用的影响

内存泄漏对于 app 没有直接危害,即使有发现内存泄漏的情况,也不一定会立即引起 app 崩溃,但是通过累积效应,应用会爆出各种问题:

  1. 内存得不到释放,慢慢的会造成 app 内存溢出,导致崩溃
  2. 内存泄漏同时可能会触发系统频繁 GC,发生内存抖动,会导致系统性能问题(卡顿不流畅)
1 操作
shakebabe 在 2020-08-06 17:43:57 更新了该帖
3 回帖
请输入回帖内容 ...
  • happy
  • 其他回帖
  • pafei

    性能始终是短板😌

  • fighting

    写的通俗易懂!