安卓内存分析

表头 含义 分析重点
Class Name 类名(对象的类型) 找你自己的业务类、Activity/Fragment、Bitmap、大数组等
Allocations 该类的对象实例数量 数量异常多 → 可能重复创建或泄漏(比如 Activity 应该只有 1 个却有 5 个)
Native Size 该类对象在Native 层(C/C++)占用的内存 图片、ByteBuffer、MediaCodec 等 Native 内存大户看这里
Shallow Size 对象自身占用的内存大小(不含它引用的对象) 看单个对象本身的开销(比如 byte \[\]、long \[\] 这种数组类)
Retained Size 对象自身 + 它能直接 / 间接引用到的所有对象的总内存 最关键指标:代表如果这个对象被 GC 回收,能释放多少内存

内存大户:

  1. byte[]:

    • Allocations:89,643 个
    • Shallow Size:10,951,673 字节(约 10.4 MB)
    • Native Size:99,804,707 字节(约 95.2 MB)→ 说明你的 App 里有大量字节数组,且很多关联到 Native 内存(大概率是图片、音视频、网络 IO 缓存)
  2. DirectByteBuffer / DirectByteBuffer$MemoryRef:

    • Allocations:33,740 + 22,500 个
    • Shallow Size:2,024,400 + 675,000 字节→ 大量直接内存缓冲区,常见于:
      • 网络请求(OkHttp/Retrofit)
      • 音视频编解码(MediaCodec)
      • 图片加载库(Glide/Picasso 用的 Native Buffer)
  3. MediaCodec$... 系列:

    • MediaCodec$BufferMap$CodecBuffer、MediaCodec$BufferInfo 数量都在 22k+→ 明显是音视频播放 / 录制 / 推流场景在占用内存,可能是 Codec 资源没及时释放

三、下一步具体分析步骤(按优先级)

步骤 1:先确认 "谁在占内存最多"
  1. 点击 Shallow Size 或 Native Size 列标题 ,按降序排序,锁定 Top 3~5 个大户(你这里已经是 byte[]、String、DirectByteBuffer 等)
  2. 重点看:
    • 你自己的业务类(包名开头的类,比如 com.xxx.xxx)
    • Activity/Fragment:数量是否超过预期(比如关闭页面后还残留多个实例)
    • Bitmap:如果存在,看 Shallow Size 和 Native Size(Bitmap 的 Native Size 就是图片像素内存)
步骤 2:深入分析 byte[] 这个最大户(核心操作)
  1. 双击 byte[] 这一行,展开它的实例列表
  2. 选中一个大尺寸的 byte \[\] 实例(按 Shallow Size 排序,找最大的几个)
  3. 右侧面板切换到 References (引用链),看:
    • 谁在引用这个 byte \[\]?
    • 是你的业务代码?还是第三方库(Glide、OkHttp、FFmpeg、MediaCodec 等)?
    • 引用路径里有没有 静态变量(static)、单例、长生命周期对象(比如 Application、Service) ?→ 如果是静态引用持有大 byte \[\],这就是典型的内存泄漏
步骤 3:分析 DirectByteBuffer 和 MediaCodec 相关对象
  1. 双击 DirectByteBuffer ,看实例的引用链:
    • 来源:OkHttp 的响应缓存?图片加载的 Native Buffer?还是音视频流 Buffer?
    • 数量是否随操作不断上涨(比如反复进入播放页面后数量翻倍)?
  2. 看 MediaCodec 相关类:
    • 退出播放页面、停止推流后,这些对象数量是否下降?
    • 如果不下降 → 说明 Codec 资源、Surface、Buffer 没释放(比如没调用 release()、stop())
步骤 4:判断是否存在内存泄漏
  1. 先点顶部的 垃圾桶图标(Force GC),触发垃圾回收
  2. 重新捕获一次堆转储(Dump Java Heap)
  3. 对比两次:
    • 如果 byte[]、DirectByteBuffer、MediaCodec 相关对象数量几乎没减少 → 泄漏风险极高
    • 如果大幅减少 → 多半是临时缓存,属于正常波动
步骤 5:定位到具体代码行

当你在引用链里找到可疑对象后:

  • 右键引用链中的某一行 → 选择 Jump to Source(跳转到源码)
  • 直接定位到:
    • 哪个类、哪一行代码创建了这个大对象
    • 哪个地方持有了不该持有的引用(比如静态集合、单例)

四、针对你当前场景的针对性建议 💡

从你的堆转储看,明显偏向 Native/IO/ 音视频场景,建议重点排查:

  1. 图片加载 :
    • 是否用了 Glide/Picasso?有没有正确配置 skipMemoryCache、diskCacheStrategy?
    • 是否有超大图没做采样压缩(inSampleSize)?
  2. 音视频模块 :
    • 播放 / 录制结束后,是否完整调用了 MediaCodec.release()、AudioTrack.release() 等?
    • 是否复用了 Codec 而没有正确释放旧实例?
  3. 网络 / IO 缓存 :
    • OkHttp 是否配置了过大的连接池 / 缓存?
    • 是否有读写大文件后没关闭流、没释放 Buffer?
相关推荐
其实防守也摸鱼1 小时前
Fastjson 反序列化漏洞(JNDI注入)
android·数据库·安全·oracle·自动化·fastjson·反序列化
狗凯之家源码网3 小时前
微博图床 PHP 系统搭建与实战应用指南
android·开发语言·php
消失的旧时光-19434 小时前
(第一篇)JNI 多线程到底难在哪:从 Linux Thread 到 JNIEnv
android·jni·ndk
_upupup5 小时前
异常(C++)
java·开发语言·jvm
逗脑IDE6 小时前
零基础学ESP32:蓝牙控制舵机——手机一点,舵机就转!
android·智能手机
清霜之辰7 小时前
骁龙 8397 舱驾融合平台端侧大模型部署:7B 模型本地推理与 64GB 内存账本
android
烽火聊员7 小时前
Android屏幕卡顿traces.txt拉取查看
android·java·android studio
只睡四小时9 小时前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航
恋猫de小郭9 小时前
Android 原生的 Compose A2UI 也来了,你还抱着 XML 养老吗?
android·前端·flutter
程序媛_9 小时前
【JMeter】准备token文件
android·jmeter