Android 内存优化

本文深入探讨了Java内存分配模型及对象生命周期,详细介绍了APP内存组成,包括Java内存限制、物理内存及应用退到后台后的分级机制。此外,还讨论了内存三大问题:内存抖动、内存泄漏与内存溢出,并提供了实用的内存分析命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Java内存分配模型
在这里插入图片描述
二、Java对象生命周期
1、创建:为对象分配内存,构造对象
2、应用:此时对象至少被一个强引用持有
3、不可见:程序本身不再持有这个对象,但是该对象还依然存在
4、不可达:GC对该对象进行可达性分析(判断对象是否为垃圾),发现不可达,然后就会把该对象归纳成不可达状态
在这里插入图片描述
三、APP内存组成
1、Java申请的内存在" vm heap " 上,所以如果申请的内存大小超过" VM "的逻辑内存限制,就会出现内存溢出。
查看APP内存限制命令:adb shell cat /system/build.prop
在这里插入图片描述
2、设备的物理内存 cat proc/meminfo
在这里插入图片描述
3、应用退到后台杀死分级
在这里插入图片描述
oom_adj给应用定级的一个取值,范围是 [-16 15] 数字越小,越不会容易被系统杀死
AMS 也会对应用定级,用oom_score_adj [-1000 1000],越小越不会被系统杀死
app:前台可见 0
查看OOM_ADJ 的值,cat proc/pid/oom_adj
在这里插入图片描述
4、内存三大问题
1、内存抖动,会导致频繁GC,然后卡顿,比如在onDraw中new Paint() 或者 new Path()
2、内存泄漏,在当前应用周期内,该对象不再使用,但是一直被GC Root持有,导致不能被回收,使实际可用内存变小。
3、内存溢出,OOM导致原因:内存不够,内存不连续,线程数量达到上限,
5、常见分析内存命令
1、dumpsys meminfo 会把当前应用进程按照内存占用情况进行排序
在这里插入图片描述
在这里插入图片描述2、dumpsys meminfo package
如果查看到的 activities 的数量是一直增长的,那么就有可能存在内存泄漏
6、AMT工具
抓取内存快照,通过代码的方式:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ssss");
        String format = dateFormat.format(new Date(System.currentTimeMillis()));
        String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        System.out.println("lgj : absolutePath :" + absolutePath);
        File file = new File(absolutePath + "/" + format + "_lgj.hprof");
        try {
            android.os.Debug.dumpHprofData(file.getAbsolutePath());
            System.out.println("lgj : 完成dump...");
        } catch (IOException e) {
            e.printStackTrace();
        }

想要通过MAT工具查看,必须需要转化,转化命令如下
D:\AndroidStadio\sdk-as\platform-tools>hprof-conv.exe 2021-04-11_23.32.0016_lgj.hprof cc.hprof

public class C {
    private static C myC = new C();
    public static C getInstance(){
        return myC;
    }
    private D d = new D();
    private E e = new E();
    public static class A{
        private C c1 = C.getInstance();
    }
    public static class B{
        private C c2 = C.getInstance();
    }
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
    }
}
class D{
}
class E{
}

C:incoming 该对象被谁持有,有A、B、C对象的class
outgoing 该对象持有谁,持有D、E、还有自身的C class对象
在这里插入图片描述
Shallow Heap:浅堆,表示自己本身占用的内存
Retained Heap:深堆,统计结果,统计自身占用的内存以及,它自己引用别的对象内存总和

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值