当前位置: 首页 > news >正文

android 内存

  1. 进程内存组成

Android 每个 App 通常运行在独立进程里,进程内存大致分为几块:

区域说明
Java HeapJava/Kotlin 对象(new、数组、String、集合等),由 ART/Dalvik 管理
Native HeapC/C++、mallocnew(native)、JNI、相机、WebView、各类 Native SDK
Stack各线程栈空间
Code映射进内存的 so、jar、dex、apk 等
Graphics图形缓冲(Bitmap、Surface 等)
其它mmap、Ashmem 等
  1. 系统起来后,每个app 的总内存占有都是动态的,不是固定的,根据使用情况而改变,过大或系统内存紧张时,可能被LMK(Low Memory Killer)杀掉
    而每个app都是一个独立的虚拟机VM,系统会给这个进程的VM分配 相对固定的配置上限,进程总内存和 VM 内存上限 是两个概念,
    进程总内存包含 Java heap(VM 管的那块),也包含 Native 等,总内存一般不是系统预先固定分配的一个数字,而是各部分加起来、再受系统整体约束,而java Heap 的内存就是在这个VM的内存上,超过了这个指定的VM的内存 就会java oom,
    但是Navtiv层 的内存就不受VM管了,

所以会出现:Java heap 还不高,App 已经被杀 —— 多半是 Native / 图形内存高了,不是 Java OOM。

设备物理内存 8GB

├── 系统 / 其它 App

└── 你的 App 进程

├── Java Heap ← 上限例如 512MB(VM/ART 管)
├── Native Heap ← 不受 Java 512MB 限制
├── Graphics
└── 其它

└── 合起来 = 进程总内存(可能 800MB、1.5GB…)

└── 太大或系统紧张 → 可能被 LMK 杀掉
(不一定是 Java OOM)

  1. adb shell dumpsys meminfo +包名 可以查看当前对应的进程 内存区域 java heap,native heap,栈(stack)等内存分配情况

这里是上面关键的字段分析

关键行

含义
Native HeapNative 内存
Dalvik HeapJava 内存(ART 管理)
Stack线程栈
.so / .jar / .apk mmap代码与资源映射
TOTAL汇总,TOTAL PSS ≈ 进程总占用

关键列

含义
Pss Total该类内存在进程 PSS 中的贡献
Heap Size / Alloc / Freeheap 内部统计

排查 OOM / 被杀进程时:Java OOM 看 Dalvik;莫名被杀看 TOTAL PSS 和 Native/Graphics。

  1. adb shell getprop | grep -i heap 这个命令查看 查看当前设备的 VM的设置情况

    heapgrowthlimit (192m) 代表默认的每个app VM层的上限
    heapsize (512m) 当你的应用在android Manifest 中设置了 android:largeHeap=“true” ,能给到的最大内存
    heapstartsize (8m),刚启动时先给的 每个app VM层的内存

  2. VM虚拟机的创建new的对象有生命周期包括新声代和老年代等,Android vm 会根据可达性分析算法对这些对象进行gc root ,不是引用计数,所以优化方向是:断开不必要的引用(置 null、从集合 remove、取消监听、关流等),让对象变成不可达。

  3. 系统会对每个进程分等级,其中有,空进程,后台进程,服务进程,可见进程,前台进程,一层比一层等级变高,前台进程是最高的,当系统需要回收的时候会先回收空进程,整个系统的ActivityManagerService 会对每个进程进行评分是哪个等级,存在变量adj中.内存紧张时,LMK按优先级从低到高回收进程。

被杀不一定是 OOM,常常是系统主动回收,可以尝试吧进程等级调高来进行保活

  1. OOM 不只有 Java OOM,还要关注:
  • .Native OOM(大图、相机、FFmpeg等)
  • .进程总内存过大被 LMK 杀(meminfo 里 TOTAL PSS 高,但 Java heap 还不满)
  1. 出问题是要分析
  • 是 泄漏(内存只涨不降)还是 峰值过高(某操作瞬间很大)?
  • 是 Java 还是 Native / Graphics?
  • 峰值对应什么操作?(进页面、切图、列表滑动、测量、WebView…)
  • 谁占最大?(Bitmap、byte[]、String、自定义大数组…)
  • 为何还被引用?(从 GC Root 跟引用链)
  1. 分析的工具
  • 使用命令 adb shell dumpsys meminfo +包名 看 PSS、Java/Native/Graphics 内存使用情况
  • Android Studio Memory Profiler 实时 Java/Native 曲线、分配记录、Heap Dump,每个对象引用链路
  • LeakCanary 开发期泄漏查看内存泄漏
  • Perfetto / Systrace 和 GC、卡顿一起看

总结 :
内存过高会导致 GC 频繁、卡顿、发热,严重时 Java OOM 或进程因总内存过大被系统杀掉。内存管理要点是:合理分配、避免泄漏、及时释放不再需要的引用与资源。

排查上:用 Memory Profiler 看内存随时间变化,峰值时对照业务, Heap Dump,每个对象引用链路;用 LeakCanary 开发期泄漏查看内存泄漏

优化上:依据 可达性(GC Roots 根搜索),断开多余强引用、取消监听、关闭流、清理缓存,让对象可被回收;同时关注 Native/Graphics,不只看 Java heap堆。

Android Studio Memory Profiler 的使用

  1. 当点击profile 的时候,会出现如图下面的画面,右边红色区域 就是看内存,

我们主要是 看 View Live Telemetry 和 Analyze Memory Usage Heap Dump 快照 ,点击Start anyway 就会开启


Past Recordings 是你对Home 每个模块点击区域操作的记录

  1. 我们先来使用 View Live Telemetry 如何使用


如图,因为我们只是分析内存,所以我们只需要看 MEMORY 下面部分,就是对应的当前进程内存的波动形式, 以及具体每个部分占用多少内存

最底下的蓝色模块趋势就是我们着重会看的java 内存使用部分
而左脚的删除垃圾按钮就是 点击可以进行 人为 手动 gc,一旦gc 包括人为手动gc或者进程被gc操作了,那么下吗就会有个对应时间的的垃圾图标,

Live Telemetry 能做什么、不能做什么?
Live Telemetry 是用来看内存总趋势,每个操作每个时间点每个场景对应的内存趋势波动,如果你手动强制gc 内存能大幅度下降还好,如果gc 不能下降,一直占用着,那么怀疑是有泄漏或者对象持有了大内存,那么这个时候,你想分析具体,当前对应指定的场景和时间点每个对象对象占用对谁内存,每个对象对应的引用链路是如何,

那么就需要使用工具 Analyze Memory Usage Heap Dump 快照

  1. Analyze Memory Usage Heap Dump 快照 ,快照的意思就是对某个时间点进行拍照记录当下场景 所有对象的内存占用情况
    现在我们来学习如何在快照中看对所有对象象内存占用情况和每个对象的引用链路

现在我们进行模拟下泄漏场景,手动代码制造泄漏,

我们创建了一个单例对象MemoryScenarioManager,然后单例对象 里面有个 leakedByteArrays ,然后他添加了字节
而由于是静态的,所有你gc的时候是不会回收的,然后我们开下快照

如图,最上面显示着当前进程下,每个类占用的内存大小
Shallow Size :对象本身自己多大
Retained Size,删掉这个对象,能释放多少内存,其实你可以粗略理解为 Shallow Size是这个对象本身的大小,而Retained Size是这个对象携带的对象占用的大小
虽然不大准,Retained Size正确理解是 删掉这个对象能释放多少内存,因为删掉他,他携带的对象也自然会被删掉。

当我们点击对应的类后,会 出现下面的对应当前对象链路情况

References 就是 显示 这个对象整条链路状态
Thread (GC Root)
└── contextClassLoader
└── PathClassLoader
└── Object[]
└── Class
└── static INSTANCE
└── MemoryScenarioManager ← 你选中的对象
而 Fields 则是当前这个对象里面的变量对象是什么有哪些
如图我们点击Fields 就能看到 MemoryScenarioManager 里面有着 leakedByteArrays 这个对象,并且占用多少内存

http://www.jsqmd.com/news/1266397/

相关文章:

  • 怡生暖通行业排名怎么样,零套路不踩坑,2026最新口碑榜单解析 - 工业品牌热点
  • Ghidra逆向分析入门:从环境搭建到实战解析SimpleCalc程序
  • 2026 年现阶段武进诚信的厂房防水施工公司联系方式,别再瞎忙了!这招让你的厂房防水永不渗漏 - 企业推荐官【认证】
  • 2026年无锡靠谱断桥铝门窗/隔音系统门窗本地源头工厂精选合集 - 海棠依旧大
  • Unity打包报错:渲染管线配置不匹配的根源与系统解决方案
  • T-SQL 变量赋值、全局变量、流程控制+T-SQL WHILE循环、表创建与数据修改+T-SQL 视图(View)
  • # 猜数字游戏 — HarmonyOS交互逻辑与随机算法实现
  • 提示词工程:提升AI交互质量的关键技术与实践
  • 智能合同解析系统:NLP技术提升法务效率
  • 基于springboot的美食网站设计与实现
  • 液下泵正规供应商实力风云榜,口碑推荐零套路选购指南 - 工业品牌热点
  • 配电主站日志异常检测:数据集构建与智能算法实践
  • 【小程序课程设计/毕业设计】基于 SpringBoot + 微信小程序日常心血管风险自测与科普小程序的设计与实现 心脑血管疾病智能预判与健康管理小程序【附源码、数据库、万字文档】
  • 消息源加载“走火入魔”:Spring Boot 多文件国际化顺序混乱的终结指南
  • 扬州运河沿岸房屋漏水高发原因与2026本地维修方案参考 - 雨婺虹房屋维修
  • 2026 年新发布:崇阳优秀的流动摆摊虾饼机加工厂哪家强,别再花钱了!这个小机器如何让你的街边虾饼生意翻倍?-英贝特 - 行业推荐官[官方】--
  • AI浏览器技术解析:从架构变革到开发实践
  • 2026佛山厨房渗水到楼下怎么办?自来水管暗管检测方法,仪器测漏收费标准 - 宅安选房屋修缮
  • 华为MetaERP Oracle EBS R12 vs Oracle Fusion Cloud PO 接收环节完整会计核算流程对比一、底层核心架构与根本差异总览1. 核心设计分水岭表格维度 O
  • 找做全场景防腐涂料配套服务的厂家推荐,价格透明不踩坑,综合实力榜单 - 工业品牌热点
  • 2026大连厨房渗水到楼下怎么办?自来水管暗管检测方法,仪器测漏收费标准 - 宅安选房屋修缮
  • 企业级AI落地:RAG技术架构与实战优化指南
  • C++数据类型与运算符详解:从内存原理到实战避坑指南
  • 基于YOLO的智慧河道检测数据集与应用实践
  • OpenAI桌面端语音控制多Agent:环境配置与实战指南
  • 你的描述符为何“失忆”?——Python __set_name__ 的属性名自动捕获与常见踩坑指南
  • 2026 年现阶段,十堰有实力的屠宰场污水处理设备平台哪家强,揭秘:屠宰场污水处理的终极省钱秘诀-晟广源环保设备 - 行业推荐官【认证】
  • Mac系统自带OpenSSL生成RSA密钥:从原理到实战排错指南
  • 论文查重39%到8%:智能降重工具实战指南
  • 大模型技术核心方向与应用实践解析