安卓内存分析

表头 含义 分析重点
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$CodecBufferMediaCodec$BufferInfo 数量都在 22k+→ 明显是音视频播放 / 录制 / 推流场景在占用内存,可能是 Codec 资源没及时释放

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

步骤 1:先确认 "谁在占内存最多"
  1. 点击 Shallow SizeNative Size 列标题 ,按降序排序,锁定 Top 3~5 个大户(你这里已经是 byte[]StringDirectByteBuffer 等)
  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:分析 DirectByteBufferMediaCodec 相关对象
  1. 双击 DirectByteBuffer ,看实例的引用链:
    • 来源:OkHttp 的响应缓存?图片加载的 Native Buffer?还是音视频流 Buffer?
    • 数量是否随操作不断上涨(比如反复进入播放页面后数量翻倍)?
  2. MediaCodec 相关类:
    • 退出播放页面、停止推流后,这些对象数量是否下降?
    • 如果不下降 → 说明 Codec 资源、Surface、Buffer 没释放(比如没调用 release()stop()
步骤 4:判断是否存在内存泄漏
  1. 先点顶部的 垃圾桶图标(Force GC),触发垃圾回收
  2. 重新捕获一次堆转储(Dump Java Heap)
  3. 对比两次:
    • 如果 byte[]DirectByteBufferMediaCodec 相关对象数量几乎没减少 → 泄漏风险极高
    • 如果大幅减少 → 多半是临时缓存,属于正常波动
步骤 5:定位到具体代码行

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

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

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

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

  1. 图片加载
    • 是否用了 Glide/Picasso?有没有正确配置 skipMemoryCachediskCacheStrategy
    • 是否有超大图没做采样压缩(inSampleSize)?
  2. 音视频模块
    • 播放 / 录制结束后,是否完整调用了 MediaCodec.release()AudioTrack.release() 等?
    • 是否复用了 Codec 而没有正确释放旧实例?
  3. 网络 / IO 缓存
    • OkHttp 是否配置了过大的连接池 / 缓存?
    • 是否有读写大文件后没关闭流、没释放 Buffer?
相关推荐
麻瓜生活睁不开眼7 小时前
Android16修改全局桌面视图边框四直角显示为弧边圆角
android·java·深度学习
AFinalStone10 小时前
Android 7系统休眠唤醒(六)唤醒全链路
android·电源管理·休眠唤醒
雨白11 小时前
深入理解 Kotlin 协程 (九):互通有无,解构 Channel 缓冲策略与底层无锁机制
android·kotlin
灯塔@kuaidao12 小时前
平台交叉编译名词解释与基础流程
android
程序员天天困12 小时前
Arthas ognl 表达式从入门到实战:掌握在线调试最强的表达式引擎
java·jvm·后端
__Witheart__13 小时前
3568 Android otg模式下adb热拔插不识别
android·adb·rockchip
长不胖的路人甲15 小时前
Serial 串行、Parallel 并行、CMS 并发收集器
java·开发语言·jvm
明天…ling15 小时前
Upload-Labs (Pass1-Pass21) 完整通关思路与源码分析
android·网络安全·渗透测试·burpsuite·upload-labs·文件上传绕过·靶场复现
__Witheart__15 小时前
3568 Android ntp校时使用
android·rockchip
wddptwd2816 小时前
android studio 报错怎么处理 java.lang.NullPointerException
android·java·android studio