Android性能优化:看完这篇文章,至少解决 APP 中 90 % 的内存异常问题

本文详细介绍了Android应用中常见的内存优化问题,包括内存泄漏的成因和解决方法,如线程共享区、引用计数算法与可达性分析算法的比较,以及强引用、软引用、弱引用和虚引用的回收状态。同时,文章列举了多种分析内存的工具,如MAT、LeakCanary等,并提供了实际案例解析内存泄漏,包括单例、Handler、静态变量等问题及其解决方案。
摘要由CSDN通过智能技术生成

注意

  • 在 hotspotVM 中把虚拟机栈和本地方法栈合为了一个栈区

线程共享区

方法区

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

  • ClassLoader 加载类信息

  • 常量、静态变量

  • 编译后的代码

  • 会出现 OOM

  • 运行时常量池

  • public static final

  • 符号引用类、接口全名、方法名

java 堆 (本次需要优化的地方)

  • 虚拟机能管理的最大的一块内存 GC 主战场

  • 会出现 OOM

  • 对象实例

  • 数据的内容

JAVA GC 如何确定内存回收


随着程序的运行,内存中的实例对象、变量等占据的内存越来越多,如果不及时进行回收,会降低程序运行效率,甚至引发系统异常。

目前虚拟机基本都是采用可达性分析算法,为什么不采用引用计数算法呢?下面就说说引用计数法是如果统计所有对象的引用计数的,再对比可达性分析算法是如何解决引用计数算法的不足。下面就来看下这 2 个算法:

引用计数算法

每个对象有一个引用计数器,当对象被引用一次则计数器加一,当对象引用一次失效一次则计数器减一,对于计数器为 0 的时候就意味着是垃圾了,可以被 GC 回收。

下面通过一段代码来实际看下

public class GCTest {

private Object instace = null;

public static void onGCtest() {

//step 1

GCTest gcTest1 = new GCTest();

//step 2

GCTest gcTest2 = new GCTest();

//step 3

gcTest1.instace = gcTest2;

//step 4

gcTest2.instace = gcTest1;

//step 5

gcTest1 = null;

//step 6

gcTest2 = null;

}

public static void main(String[] arg) {

onGCtest();

}

}

分析代码

//step 1 gcTest1 引用 + 1 = 1

//step 2 gcTest2 引用 + 1 = 1

//step 3 gcTest1 引用 + 1 = 2

//step 4 gcTest2 引用 + 1 = 2

//step 5 gcTest1 引用 - 1 = 1

//step 6 gcTest2 引用 - 1 = 1

很明显现在 2 个对象都不能用了都为 null 了,但是 GC 确不能回收它们,因为它们本身的引用计数不为 0 。不能满足被回收的条件,尽管调用 System.gc() 也还是不能得到回收, 这就造成了 内存泄漏 。当然,现在虚拟机基本上都不采用此方式。

可达性分析算法

从 GC Roots 作为起点开始搜索,那么整个连通图中额对象边都是活对象,对于 GC Roots 无法到达的对象便成了垃圾回收的对象,随时可能被 GC 回收。

可以作为 GC Roots 的对象

  • 虚拟机栈正在运行使用的引用

  • 静态属性 常量

  • JNI 引用的对象

GC 是需要 2 次扫描才回收对象,所以我们可以使用 finalize 去救活丢失的引用

@Override

protected void finalize() throws Throwable {

super.finalize();

instace = this;

}

到了这里,相信大家已经能够弄明白这 2 个算法的区别了吧?反正对于对象之间循环引用的情况,引用计数算法无法回收这 2 个对象,而可达性是从 GC Roots 开始搜索,所以能够正确的回收。

不同引用类型的回收状态

强引用

Object strongReference = new Object()

如果一个对象具有强引用,那垃圾回收器绝不会回收它,当内存空间不足, Java 虚拟机宁愿抛出 OOM 错误,使程序异常 Crash ,也不会靠随意回收具有强引用的对象来解决内存不足的问题.如果强引用对象不再使用时,需要弱化从而使 GC 能够回收,需要࿱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值