移动开发的内存管理

移动系统对资源的限制和要求

移动操作系统现对于PC端的一个首要特点就是资源有限,比如内存、电池、网络的不确定等等,这些资源相对于PC端来说都很有限,当然对于发展到今天的移动端设备来说,这个已经不算是一个大问题了,不过,在移动端开发中,针对资源有限的问题都是一个不得不正视的问题。本文主要针对内存这一块进行阐述,针对移动网络的特点、电池优化的问题、有后续系列阐述文章。

移动操作系统的几个主要特点

  • 移动设备需要便携,所以需要携带电池,需要专门的电池管理,这一点,笔者当年首次学习Symbian系统时却有体会;
  • 移动设备通常情况下,屏幕比较小,但是需要展示的信息一点也不少,所以,就需要在界面设计以及交互设计上(UI UE)需要更多的想象力,需要更好的更人性化的设计,需要面对的情况也更复杂;
  • 由于移动设备的大部分都需要电池供电,所以,在选择CPU时,也就必须考虑好CPU的功耗问题,复杂指令集的基本不建议在考虑之列。
  • 同样由于电池所限,使用的内存(memory)和存储相对于PC桌面系统来说都相当受限制。
  • 由于移动设备资源所限,大部分移动设备操作系统,都需要分时复用来管理所有的需要运行的程序(通常叫App)。
    • 现阶段流行的移动操作系统主要是ios和android,其中大部分程序都运行在后台情况下,都由系统层面管理App所占用的各类资源,比如内存,当程序后台运行时,大部分情况下内存都会被回收。
    • 移动操作系统一般情况下都会限制每个应用所消耗的资源总量。
    • 作为App开发者,管理好自身App所消耗的资源是一个应尽的义务。
  • 管理

Android内存管理机制浅析

Android是2007年Google在收购基础上推出的基于Linux操作系统的开源移动操作系统,该平台由操作系统、中间件、用户界面和应用软件组成。

Android的系统架构和其操作系统一样,采用了分层的架构。[
Android结构

Android结构

从架构图看,Android分为四个层,分别是应用程序层、应用程序框架层、系统运行库层和Linux层。

Android应用开发

在Android平台上开发应用程序,包括java 和C++(for Native)。

android平台的内存管理

一般情况下(多进程例外)每个应用都会由系统分配一个进程(zygote)资源。这段Android代码可以获取当前进程的内存情况。

        ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        int memClass = activityManager.getMemoryClass();
        int maxClass = activityManager.getLargeMemoryClass();

任何一个进程最多可以获取的内存资源时有限的。

内存优化思路

强引用与弱引用

  • 在一个Activity生命周期中,其中所有定义的变量的生命周期都和Activty保持一致,如果用强引用的话,那么变量所指向的内存和Activity生命周期保持一致,但是在很多情况下,从逻辑上这个成员变量已经不需要了,由于强引用其所指向的内存区域也保持一样的什么周期,有点得不偿失。
  • 这种情况下,可以选择弱引用,所谓弱引用就是指其指向的内存区域,在内存比较紧张的时候可以被GC。这样就可以减少内存的使用。
    WeakReference<ForeEngine> mWeakForeEngine;
    ForeEngine  mForeEngine;

其中:

  • mForeEngine是强引用,mWeakForeEngine是弱引用
  • mWeakForeEngine指向的内存在mWeakForeEngine运行过程中可能会被回收

弱引用的初始化

     mWeakForeEngine  = new WeakReference<ForeEngine>(foreEngine) ;

弱引用的使用

      ForeEngine foreEngine = mWeakForeEngine.get();
     if(foreEngine == null) {
     //  todo
     }

关注内存大户Bitmap

待续

Android内存管理原理简析

Java虚拟机模型

JVM内存模型,java虚拟机在构建RunTime运行时数据内存分配,
内存主要分为方法区,虚拟机栈,本地方法栈,堆,PCR程序计数器。

JVM内存模型示意

Android的改进

- 寄存器和栈的区别
     * JVM虚拟机基于栈,DVM基于寄存器。*
- Dalvik和java虚拟的区别  dex class的区别
-  dalvik art的改进
   android虚拟机都使用页式和memory mapping方式进行内存管理,虚拟机分配并决定了内存的生命周期,并且使用GC(*garbage collection*)来回收已分配但是不再使用的内存片段,GC的主要工作主要分为两个部分:
     1)找到内存中不再使用的数据片段
     2)回收这些资源
   分配内存资源主要是分代管理,刚刚分配的内存区域叫Young Generation。
   对象在Young Generation时间比较长之后,就会被划到Older Generation,还有一个permanent generation。
    尽管内存回收的速度较快,但是由于会在程序运行过程中的停下执行GC,不可避免的的会影响程序的运行,一旦GC边界条件被触发,系统就会停止当前进程,开始GC。
    关于GC的详细机制详见,ref:
- Android Runtime(ART)的进一步改进措施
    1) ART中暂停次数相比于Dalvik有减少,从两次减为一次;
    2)ART GC 一样有暂停中断,不一样之处在于,ART在有些阶段比如引用过程,sytem sweeping过程,等阶段中可以并发的执行GC。

DVM算法简析

  • 程序运行过程中,不断申请新的对象消耗内存,直到用完所有,然后创建新的对象需要内存的时候,暂停运行,出发GC 回收,器原理就是从GC Roots开始,将整个内存遍历,保留所有被直接以及间接用的内存区域,余下的被回收。
    该算法可以解决内存的问题,释放内存。
  • 但是缺点一样存在,1 从GC Roots开始的遍历是一个递归调用,这个过程本身会消耗很多资源,一方面在内存不多时候消耗内存递归,另一方面,如果遍历非常深的话,消耗的时间资源也很明显。所有后来的android系统优化了这个过程,另开启线程逐步释放内存,尽量不影响程序的正常运行。也就是逐步GC,还有一个叫CMS(concurrent mark sweep)。
  • 下面是代码

    1 启动VM

\dalvik\vm\Init.cpp
/*
* VM initialization.  Pass in any options provided on the command line.
* Do not pass in the class name or the options for the class.
*
* Returns 0 on success.
*/
std::string dvmStartup(int argc, const char* const argv[],
bool ignoreUnrecognized, JNIEnv* pEnv)

其中 启动的内容很多,有兴趣的可以参考源代码。

2 GC 启动

在main heap上采用mmap管理内存。
dalvik\vm\alloc\alloc.cpp

/*
* Initialize the GC universe.
*
* We're currently using a memory-mapped arena to keep things off of the
* main heap.  This needs to be replaced with something real.
*/
bool dvmGcStartup()
{
dvmInitMutex(&gDvm.gcHeapLock);
pthread_cond_init(&gDvm.gcHeapCond, NULL);
return dvmHeapStartup();
}

3 GC heap启动

dalvik\vm\alloc\Heap.cpp
初始化GC heap 并建立VM card table。

/*
* Initialize the GC heap.
*
* Returns true if successful, false otherwise.
*/
bool dvmHeapStartup()
{
GcHeap *gcHeap;
if (gDvm.heapGrowthLimit == 0) {
gDvm.heapGrowthLimit = gDvm.heapMaximumSize;
}
gcHeap = dvmHeapSourceStartup(gDvm.heapStartingSize,
gDvm.heapMaximumSize,
gDvm.heapGrowthLimit);
if (gcHeap == NULL) {
return false;
}
gcHeap->ddmHpifWhen = 0;
gcHeap->ddmHpsgWhen = 0;
gcHeap->ddmHpsgWhat = 0;
gcHeap->ddmNhsgWhen = 0;
gcHeap->ddmNhsgWhat = 0;
gDvm.gcHeap = gcHeap;
/* Set up the lists we'll use for cleared reference objects.
*/
gcHeap->clearedReferences = NULL;
if (!dvmCardTableStartup(gDvm.heapMaximumSize, gDvm.heapGrowthLimit)) {
LOGE_HEAP("card table startup failed.");
return false;
}
return true;
}

4

dalvik\vm\alloc\HeapSource.cpp
为了不和zygote heap的内存发生交集,在首次fork之前调用它,这个仍然会有一些造成小片段内存的问题存在

/*
* This is called while in zygote mode, right before we fork() for the
* first time.  We create a heap for all future zygote process allocations,
* in an attempt to avoid touching pages in the zygote heap.  (This would
* probably be unnecessary if we had a compacting GC -- the source of our
* troubles is small allocations filling in the gaps from larger ones.)
*/
bool dvmHeapSourceStartupBeforeFork()
{
HeapSource *hs = gHs; // use a local to avoid the implicit "volatile"
HS_BOILERPLATE();
assert(gDvm.zygote);
if (!gDvm.newZygoteHeapAllocated) {
/* Ensure heaps are trimmed to minimize footprint pre-fork.
*/
trimHeaps();
/* Create a new heap for post-fork zygote allocations.  We only
* try once, even if it fails.
*/
ALOGV("Splitting out new zygote heap");
gDvm.newZygoteHeapAllocated = true;
return addNewHeap(hs);
}
return true;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容