内存泄漏是引发Android应用崩溃常见的缘由,每一个Android开发人员都应该明白怎么避免发送。 经常使用的分析内存的工具备 Android Profiler 和 LeakCanary。java
Android Profiler 是Android Studio提供的一个工具,用于实时观察应用的状况,包括:内存、CPU、网络等。android
LeakCanary 是一个第三方库,用于分析内存泄漏。官方地址:square.github.io/leakcanary/git
是什么致使了内存泄漏呢?当你的代码为一个对象分配了内存,可是却没有释放,就会形成内存泄漏,固然没有释放的缘由有不少种。github
不论是什么缘由,没有释放,是由于这个对象依然被别的对象引用,可是这些被引用的对象应该是要被销毁的。网络
Android 为每一个应用限制的最大内存使用量,当使用的内存超过最大值之后就会引起OOM,是程序奔溃,因此咱们要严格限制内存的使用。框架
系统回收内存的时候,你的程序会暂停,但一般这个过程是很是短暂的,通常用户感知不到。ide
可是有的时候你注意到你的程序变的缓慢和掉针,这是由于回收内存已经赶不上分配内存的速度了。工具
当内存泄漏发生的时候,内存会不断的增长,致使不断的触发gc,进而致使程序卡顿,甚至系统会强制杀死你的程序已便回收内存。字体
基于这些缘由,咱们必须的关注内存。优化
Java内存模型分为Jvm内存模型和Jmm内存模型。Jvm是java虚拟机内存模型,而Jmm内存模型是只为java程序服务。咱们一般讨论的Java内存模型,更多的是在讨论Jvm。
Jvm内存模型中按照线程是否独占,能够分为两部分。线程独占内存区有栈,本地方法栈和程序计数器,全部线程共享的有堆和方法区。
咱们可使用Android Sudio的 Memory Profiler 中查看App的内存状况。
内存计数中的类别以下:
Java:从 Java 或 Kotlin 代码分配的对象的内存。
Native:从 C 或 C++ 代码分配的对象的内存。 即便您的应用中不使用 C++,您也可能会看到此处使用的一些原生内存,由于 Android 框架使用原生内存表明您处理各类任务,如处理图像资源和其余图形时,即便您编写的代码采用 Java 或 Kotlin 语言。
Graphics:图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。(请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)
Stack:您的应用中的原生堆栈和 Java 堆栈使用的内存。这一般与您的应用运行多少线程有关。
Code:您的应用用于处理代码和资源(如 dex 字节码、通过优化或编译的 dex 代码、.so 库和字体)的内存。
Others:您的应用使用的系统不肯定如何分类的内存。
Allocated:您的应用分配的 Java/Kotlin 对象数。此数字没有计入 C 或 C++ 中分配的对象。
若是链接到搭载 Android 7.1 及更低版本的设备,只有在 Memory Profiler 链接到您运行的应用时,才开始此分配计数。所以,您开始分析以前分配的任何对象都不会被计入。不过,Android 8.0 及更高版本附带一个设备内置分析工具,该工具可跟踪全部分配,所以,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。
Android 中常见的内存泄漏来自Activity,Service,View等组件的不当使用。好比当一个Activity在被销毁后,还被别的对象持有的状况下,gc就无法回收这个activity,致使内存泄漏。 咱们来看一个内存泄漏的例子:
class MemoryLeakDemoActivity : AppCompatActivity() {
companion object {
private var activities: MutableList<Activity>? = mutableListOf()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_memory_leak_demo)
// 这会形成内存泄漏
activities?.add(this)
}
}
复制代码
这段代码中,在onCreate方法咱们把当前activity对象加入到单例列表中,这样当这个activity被销毁后,却不能被gc回收,由于其对象还在被引用,这就形成了内存的泄漏。
Android 对内存的要求的比较严格,每一个应用程序可以使用的内存都是有限的,不合理的使用内存会形成程序卡顿,甚至崩溃,因此每个开发者都应该要关注内存的使用状况。