进程内存Android进程的内存管理分析

android内存占用分析,Android App性能评测分析-内存篇 1、内存了解在Android App的性能优化的各个部分里,内存方面的知识较多且不易理解,内存的问题绝对是最令人头疼的一部分,需要对内存基础知识、内存分配、内存管理机制等非常熟悉,才能排查问题。1.1 了解进程的地址空间在32位操作系统中,进程的地址空间为0到4GB,这里主要说明一下Stack和Heap:Stack空间(进栈和出栈):由操作系统控制,其中主要存储函数地址、函数参数、局部变量等等,所... 阅读详情

最近应用开发的过程中涌现了一个小问题,顺便记录一下原因和方法--进程内存

    尊敬原创作者,转载请注明出处:

    http://blog.youkuaiyun.com/gemmem/article/details/8920039

    

    最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去分析内存管理,没有能全局掌控,缺乏系统性阐述,而且有些观点有误。

    这样对Android内存管理停止局部性分析,很难使读者建立系统性概念,没法真正懂得内存管理,对提高系统优化和系统稳定性分析方面的能力是不敷的。

    我结合自己的一些思考和懂得,从微观层面上,对内存管理做一个全局性的分析,在此与大家交流分享。

    

    首先,回想一下基础知识,基础知识是懂得系统机制的前提和关键:

    1、  进程的地址空间

    在32位操纵系统中,进程的地址空间为0到4GB,

    示意图如下:

    

    

 进程和内存

    图1

 

    这里主要说明一下Stack和Heap:

    Stack空间(进栈和出栈)由操纵系统控制,其中主要存储函数地址、函数参数、局部变量等等,所以Stack空间不须要很大,一般为几MB大小。

    Heap空间由程序控制,程序员可以应用malloc、new、free、delete等函数调用来操纵这片地址空间。Heap为程序完成各种复杂任务提供内存空间,所以空间比较大,一般为几百MB到几GB。正是因为Heap空间由程序员管理,所以容易涌现应用不当导致严重问题。

 

    2、进程内存空间和RAM之间的关系

    进程的内存空间只是虚拟内存(或者叫作逻辑内存),而程序的运行须要的是实实在在的内存,即物理内存(RAM)。在必要时,操纵系统会将程序运行中请求的内存(虚拟内存)映射到RAM,让进程能够应用物理内存。

    RAM作为进程运行不可或缺的资源,对系统性能和稳定性有着决定性影响。另外,RAM的一部分被操纵系统留作他用,比如显存等等,内存映射和显存等都是由操纵系统控制,我们也不必过量地关注它,进程所操纵的空间都是虚拟地址空间,没法直接操纵RAM。

    示意图如下:

    

    进程和内存

    图2

    

    基础知识分析到这里,如果读者懂得以上知识有障碍,请好好恶补一下基础知识,基础理论知识至关重要。 

    

 

    3、  Android中的进程

    (1)   native进程:采取C/C++实现,不包括dalvik实例的进程,/system/bin/目录上面的程序文件运行后都是以native进程形式存在的。如图           3,/system/bin/surfaceflinger、/system/bin/rild、procrank等就是native进程。

 

    (2)   java进程:Android中运行于dalvik虚拟机之上的进程。dalvik虚拟机的宿主进程由fork()系统调用创建,所以每一个java进程都是存在于一个native进程中,因此,java进程的内存分配比native进程复杂,因为进程中存在一个虚拟机实例。如图3,Android系统中的应用程序基本都是java进程,如桌面、电话、联系人、状态栏等等。

    

    

    进程和内存

    图3

 

 

    4、  Android中进程的堆内存

    图1和图4分别分析了native process和java process的结构,这个是我们程序员须要深刻懂得的,进程空间中的heap空间是我们须要重点关注的。heap空间完全由程序员控制,我们应用的malloc、C++ new和java new所请求的空间都是heap空间, C/C++请求的内存空间在native heap中,而java请求的内存空间则在dalvik heap中。

    

    

    进程和内存

    图4

 

    5、  Android的 java程序为什么容易涌现OOM

    这个是因为Android系统对dalvik的vm heapsize作了硬性限制,当java进程请求的java空间超越阈值时,就会抛出OOM异常(这个阈值可以是48M、24M、16M等,视机型而定),可以通过adb shell getprop | grep dalvik.vm.heapsize查看此值。

    也就是说,程序发生OMM并不表示RAM不足,而是因为程序请求的java heap对象超越了dalvik vm heapsize。也就是说,在RAM充分的情况下,也可能发生OOM。

    这样的计划仿佛有些不合理,但是Google为什么这样做呢?这样计划的目的是为了让Android系统能同时让比较多的进程常驻内存,这样程序启动时就不必每次都重新加载到内存,能够给用户更快的响应。迫使每一个应用程序应用较小的内存,移动设备非常有限的RAM就能使比较多的app常驻其中。但是有一些大型应用程序是没法忍受vm heapsize的限制的,后面会分析如何让自己的程序跳出vm heap size的限制。

 

    6、  Android如何应答RAM不足

    在第5点中提到:java程序发生OMM并不是表示RAM不足,如果RAM真的不足,会发生什么呢?这时Android的memory killer会起作用,当RAM所剩不多时,memory killer会杀死一些优先级比较低的进程来释放物理内存,让高优先级程序得到更多的内存。我们在分析log时,看到的进程被杀的log,如图5,往往就是属于这种情况。

    

    

    进程和内存

    图5

    7、  如何查看RAM应用情况

    可以应用adb shell cat /proc/meminfo查看RAM应用情况:

    MemTotal:        396708 kB

    MemFree:           4088 kB

    Buffers:           5212 kB

    Cached:          211164 kB

    SwapCached:           0 kB

    Active:          165984 kB

    Inactive:        193084 kB

    Active(anon):    145444 kB

    Inactive(anon):     248 kB

    Active(file):     20540 kB

    Inactive(file):  192836 kB

    Unevictable:       2716 kB

    Mlocked:              0 kB

    HighTotal:            0 kB

    HighFree:             0 kB

    LowTotal:        396708 kB

    LowFree:           4088 kB

    SwapTotal:            0 kB

    SwapFree:             0 kB

    Dirty:                0 kB

    Writeback:            0 kB

    AnonPages:       145424 kB

    ……

    ……

    这里对其中的一些字段停止解释:

    MemTotal:可以应用的RAM总和(小于实际RAM,操纵系统预留了一部分)

    MemFree:未应用的RAM

    Cached:缓存(这个也是app可以请求到的内存)

    HightTotal:RAM中地址高于860M的物理内存总和,只能被用户空间的程序应用。

    HightFree:RAM中地址高于860M的未应用内存

    LowTotal:RAM中内核和用户空间程序都可以应用的内存总和(对于512M的RAM: lowTotal= MemTotal)

    LowFree: RAM中内核和用户空间程序未应用的内存(对于512M的RAM: lowFree = MemFree)

 

    8、  如何查看进程的内存信息

    (1)、应用adb shell dumpsys meminfo + packagename/pid:

    从图6可以看出,com.example.demo作为java进程有2个heap,native heap和dalvik heap,

    native heap size为159508KB,dalvik heap size为46147KB

    

    

 进程和内存

    图6 

 

 

    (2)、应用adb shell procrank查看进程内存信息

        如图7:

    

    进程和内存

    图7

 

    解释一些字段的意思:

    VSS- Virtual Set Size 虚拟耗用内存(包括同享库占用的内存)

    RSS- Resident Set Size 实际应用物理内存(包括同享库占用的内存)

    PSS- Proportional Set Size 实际应用的物理内存(比例分配同享库占用的内存)

    USS- Unique Set Size 进程独自占用的物理内存(不包括同享库占用的内存)

    一般来说内存占用大小有如下法则:VSS >= RSS >= PSS >= USS

 

    注意:procrank可以查看native进程和java进程,而dumpsys meminfo只能查看java进程。

    每日一道理 
共和国迎来了她五十诞辰。五十年像一条长河,有急流也有缓流;五十年像一幅长卷,有冷色也有暖色;五十年像一首乐曲,有低音也有高音;五十年像一部史诗,有痛苦也有欢乐。长河永远奔流,画卷刚刚展开,乐曲渐趋高潮,史诗还在续写。我们的共和国正迈着坚定的步伐,跨入新时代。

 

    9、  应用程序如何绕过dalvikvm heapsize的限制

    对于一些大型的应用程序(比如游戏),内存应用会比较多,很容易超超出vm heapsize的限制,这时怎么保证程序不会因为OOM而崩溃呢?

    (1)、创建子进程

               创建一个新的进程,那么我们就可以把一些对象分配到新进程的heap上了,从而达到一个应用程序应用更多的内存的目的,当然,创建子进程会增长系统开销,而且并不是全部应用程序都合适这样做,视需求而定。

    创建子进程的方法:应用android:process标签

    (2)、应用jni在native heap上请求空间(推荐应用)

      nativeheap的增长并不受dalvik vm heapsize的限制,从图6可以看出这一点,它的native heap size已经远远超越了dalvik heap size的限制。

    只要RAM有剩余空间,程序员可以一直在native heap上请求空间,当然如果 RAM快耗尽,memory killer会杀进程释放RAM。大家应用一些软件时,有时候会闪退,就多是软件在native层请求了比较多的内存导致的。比如,我就碰到过UC web在浏览内容比较多的网页时闪退,原因就是其native heap增长到比较大的值,占用了大批的RAM,被memory killer杀掉了。

    (3)、应用显存(操纵系统预留RAM的一部分作为显存)

    应用OpenGL textures等API,texture memory不受dalvik vm heapsize限制,这个我没有实际过。再比如Android中的GraphicBufferAllocator请求的内存就是显存。

     

    10、Bitmap分配在native heap还是dalvik heap上?

    一种风行的观点是这样的:

    Bitmap是jni层创建的,所以它应该是分配到native heap上,并且为了解释bitmap容易导致OOM,提出了这样的观点:

              native heap size + dalvik heapsize <= dalvik vm heapsize

    详情请看:http://devspirit.blog.163.com/blog/static/16425531520104199512427/

 

    但是请大家看看图6,native heap size为159508KB,远远超越dalvik vm heapsize,所以,事实证明以上观点是不正确的。

 

    正确的观点:

    大家都晓得,过量地创建bitmap会导致OOM异常,且native heapsize不受dalvik限制,所以可以得出结论:

    Bitmap只能是分配在dalvik heap上的,因为只有这样才能解释bitmap容易导致OOM。

 

    但是,有人可能会说,Bitmap确实是应用java native方法创建的啊,为什么会分配到dalvik heap中呢?为了解决这个疑难,我们还是分析一下源码:

    触及的文件:

framework/base/graphic/java/Android/graphics/BitmapFactory.java framework/base/core/jni/Android/graphics/BitmapFactory.cpp framework/base/core/jni/Android/graphics/Graphics.cpp

    BitmapFactory.java里头有几个decode***方法用来创建bitmap,终究都市调用:

    private staticnative Bitmap nativeDecodeStream(InputStream is, byte[] storage,Rect padding,Options opts);

    而nativeDecodeStream()会调用到BitmapFactory.cpp中的deDecode方法,终究会调用到Graphics.cpp的createBitmap方法。

 

    我们来看看createBitmap方法的实现:

jobjectGraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, boolisMutable, jbyteArray ninepatch, int density) { SkASSERT(bitmap); SkASSERT(bitmap->pixelRef()); jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer, isMutable, ninepatch,density); hasException(env); // For the side effectof logging. return obj; }

 

    从代码中可以看到bitmap对象是通过env->NewOject( )创建的,到这里困惑就解开了,bitmap对象是虚拟机创建的,JNIEnv的NewOject方法返回的是java对象,并不是native对象,所以它会分配到dalvik heap中。

 

    11、java程序如何才能创建native对象

    必须应用jni,而且应该用C语言的malloc或者C++的new关键字。实例代码如下:

JNIEXPORT void JNICALLJava_com_example_demo_TestMemory_nativeMalloc(JNIEnv *, jobject) { void * p= malloc(1024*1024*50); SLOGD("allocate50M Bytes memory"); if (p !=NULL) { //memorywill not used without calling memset() memset(p,0, 1024*1024*50); } else SLOGE("mallocfailure."); …. …. free(p); //free memory }

    或者:

JNIEXPORT voidJNICALL Java_com_example_demo_TestMemory_nativeMalloc(JNIEnv *, jobject) { SLOGD("allocate 50M Bytesmemory"); char *p = new char[1024 * 1024 * 50]; if (p != NULL) { //memory will not usedwithout calling memset() memset(p, 1, 1024*1024*50); } else SLOGE("newobject failure."); …. …. free(p); //free memory }

    这里对代码中的memset做一点说明:

       new或者malloc请求的内存是虚拟内存,请求以后不会立即映射到物理内存,即不会占用RAM,只有调用memset应用内存后,虚拟内存才会真正映射到RAM。

    

    本文旨在让大家对Android内存管理有一个整体性的意识,侧重全局性懂得,希望对大家有效。

Win10 / Win11 启用 Hyper-V 虚拟机详细教程(图文+命令行全攻略) 摘要:本文详细介绍Windows10/11系统启用Hyper-V虚拟化平台的方法,包含专业版/企业版的图形界面和PowerShell命令行操作,以及家庭版通过脚本强制启用的特殊方案。内容涵盖版本支持对比、操作步骤图解、常见问题解答和性能优化建议,帮助开发者快速搭建虚拟化环境进行多系统测试。附微软官方文档参考链接和详细操作示意图。 阅读详情

相关推荐

python爬虫入门教程(非常详细)

爬虫指的是一种自动化程序,能够模拟人类在互联网上的浏览行为,自动从互联网上抓取、预处理并保存所需要的信息。爬虫运行的过程一般是先制定规则(如指定要抓取的网址、要抓取的信息的类型等),紧接着获取该网址的HTML源代码,根据规则对源代码进行解析和抽取,最后进行处理和保存。爬虫在实际应用中广泛使用,如搜索引擎、大数据分析、交易数据采集等领域,都需要用到爬虫技术来实现信息的定向采集和处理。

工宗浩生财指南针 2万+

一次进程虚拟内存占用超过200G问题分析

一次性分配大块内存的,可通过gdb单步骤执行快速确认具体位置持续小内存分配逐渐增长的,借助工具采集数据分析。

qq_29022265的博客 1281

【OpenClaw 故障排查完全指南】

OpenClaw 故障排查指南摘要 本指南针对OpenClaw 2026.2.26版本常见问题提供解决方案,适用于Windows/Linux/macOS平台。 核心问题及修复方案: 飞书插件连接失败:删除冲突插件或重装OpenClaw Ollama认证错误:设置环境变量OLLAMA_API_KEY="ollama-local" 配置警告:可安全忽略的安全扫描提示 端口占用:查找并终止占用18789端口的进程 插件重复加载:清理重复插件目录 快速修复: 提供一键修复PowerShell脚本

weixin_37572294的博客 1万+

分析并优化 Android 应用内存占用

官方视频翻译,如需转载,请注明作者:Yuloran (t.cn/EGU6c76) 演讲人介绍 Rechard Uhler,Android Runtime 开发工程师。为便于写作,笔者将以第一人称视角对视频内容进行概述。 视频地址 前言 想要进行内存优化,就必须对 Android 内存管理机制有比较深入的了解,这样才能保证应用在低端机上也能有良好的表现。不同的内存类型,包括 Shared Me...

weixin_34242658的博客 2306

Adams中AKISPL和DX函数的妙用:打造精准的非线性衬套模型

本文深入探讨了在Adams动力学软件中,如何巧妙运用AKISPL插值函数与DX等位移测量函数,构建高精度的非线性衬套模型。文章通过实战案例,详细解析了从单轴非线性刚度到完整六自由度耦合模型的实现步骤与调试技巧,帮助工程师将复杂的实验或有限元数据转化为可靠的多体动力学仿真模型,有效提升系统仿真置信度。

sky77的博客 320

从零开始安装 Windows 11 和 Ubuntu 22.04 双系统

本文详解Windows与Ubuntu 22.04双系统安装流程:需提前确认BIOS模式(UEFI/GPT或Legacy/MBR),关闭BitLocker加密、设备加密及快速启动;推荐Rufus/Ventoy制作启动盘。安装时需规划分区方案(建议单独划分EFI系统分区),注意引导器安装位置选择。双系统启动通过BIOS引导顺序管理,安装后需同步Windows与Linux系统时间。教程适配主流UEFI+GPT设备,强调操作前数据备份及Windows更新策略调整,避免兼容性问题。

萑澈的博客 3775

android内存占用分析,Android OOM 分析

前言在内存使用过程中使用不当或者超过heap size limit的时候就会出现OOM,那一般OOM 是怎么产生的,会导致什么样的结果呢?OOM简介OOM全称为Out of memory,解释为内存溢出。为了整个Android系统的内存控制需要,Android系统为每一个应用程序都设置了一个硬性的Dalvik Heap Size最大限制阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如...

weixin_31439191的博客 1313

ScanNet数据集详解

ScanNet 是一个 RGB-D 视频数据集,在超过 1500 次扫描中包含了 250 万个视图,并标注了 3D 相机位姿、表面重建和实例级的语义分割。为了收集这些数据,设计了一个易于使用且具有扩展性的 RGB-D 捕获系统,包括自动化的表面重建和众包的语义标注。如果您想下载 ScanNet 数据,请使用您的机构邮箱地址填写一份 ScanNet 使用条款协议,并发送至 scannet@googlegroups.com。压缩包是将3D的标注信息“拍扁”成2D图片的结果,对应原始视频的每一帧。

frostmelody 全网同名,大家多多关注呀~ 持续分享优质内容! 3921

【重要】进程的内存分布

开发者可以根据需要申请内存的大小、决定使用的时间长短等。但又由于这是一块系统“飞地”,所有的细节均由开发者自己把握,系统不对此做任何干预,给予开发者绝对的“自由”,但也正因如此,对开发者的内存管理提出了很高的要求。对堆内存的合理使用,几乎是软件开发中的一个永恒的话题。

xyxzlsld666的博客 1230

SAP-ABAP:SAP数据库视图(Database View)详解-创建

数据库视图是SAP中实现多表关联查询的基础工具,适合简单的跨表查询和权限控制场景。但其功能有限,对于复杂逻辑或高性能需求,建议结合CDS视图或ABAP程序开发。通过合理设计,数据库视图可显著提升开发效率和系统可维护性。它存储在数据库中,但本身不存储数据,仅通过查询动态生成结果。是一种基于物理数据库表的虚拟表,通过关联多个表(使用。

baidu_35680696的博客 1370

代码的自由之旅:用AI写出无版权烦恼的Verilog

他们还基于这个数据集,训练了一个名叫“FreeV”的AI模型,不仅能写出好用的Verilog代码,还把版权侵权的风险降到了仅3%。为了让AI安全地写Verilog,研究团队提出了三个“法宝”:一个检测AI是否会生成侵权代码的测试方法、一个干净的Verilog数据集FreeSet,还有一个基于FreeSet训练的AI模型FreeV。AI的记忆力超强,能记住训练时见过的代码。测试发现,一些用Verilog数据训练过的AI,比如VeriGen,生成侵权代码的概率从9%涨到了15%,说明它们可能学了不该学的代码。

步子哥的博客 1810

内存 分析 android,Android进程的内存管理分析

最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误。这样对Android内存管理进行局部性介绍,很难使读者建立系统性概念,无法真正理解内存管理,对提高系统优化和系统稳定性分析方面的能力是不够的。我结合自己的一些思考和理解,从宏观层面上,对内存管理做一个全局性的介绍,在此与大家交流分享。首先,回顾一下基础知识...

weixin_36221923的博客 257

066、AR 应用中虚拟物体漂移抖动?IMU 融合 + 光流追踪的视觉里程计优化方案

AR应用中虚拟物体漂移抖动优化方案 摘要:针对AR应用中虚拟物体漂移抖动问题,提出一种IMU融合与光流追踪的视觉里程计优化方案。关键点包括:1) 采用IMU预积分技术处理高频噪声,通过中值积分计算帧间相对运动约束;2) 使用金字塔LK光流追踪像素运动,通过中值偏差法剔除异常值;3) 构建10帧滑动窗口的紧耦合优化框架,将IMU预积分约束和光流重投影约束联合优化。实验表明,该方法有效解决了时间戳未对齐导致的"跳舞箭头"现象,在手机端实现稳定30fps的AR定位精度,漂移误差降低至厘米级。特别提醒:IMU与视觉

ai技术增长的博客 161

Android进程的内存管理分析

转自:http://blog.youkuaiyun.com/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误。 这样对Android内存管理进行局部性介绍,很难使读者建立系统性概念,无法真正理解内存管理,对提高系统优化和系统稳定性分析方面的

Habby的专栏 1161

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

转载:Android进程的内存管理分析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34235105的博客 99

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Android 进程的内存管理分析

尊重原创作者,转载请注明出处: http://blog.youkuaiyun.com/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误。 这样对Android内存管理进行局部性介绍,很难使读者建立系统性概念,无法真正理解内存管理,对提高系统优化和系统

Mr_LiaBill 1086

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

上一篇: android进程与线程详解一:进程
下一篇: Android内存机制分析上篇:了解Android堆和栈
blueangle17
博客等级 码龄16年 78粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值