温故---Android 线程、进程老生常谈

进程&线程

首先明确:
程序--->指计算机能够识别和执行的指令及数据静态文件,比如Windows平台的exe文件;
进程--->程序执行必须要系统分配资源创建实体之后才能运行,这个创建运行的实体即为计算机为了管理描述而进行抽象的概念--进程;进程是系统资源分配调度的单位

通常分配给进程的资源包括独立的地址空间、寄存器、文件I/O等
在面向线程设计的系统(如当代多数操作系统、Linux 2.6及更新的版本)中,进程本身不是基本运行单位,而是线程的容器。(维基百科)

线程--->引入线程的系统,通常进程本身不参与实际任务执行所以需要真正执行任务的单元即线程,同一进程内的线程共享该进程的资源,线程只拥有自身的栈、PC寄存器和局部变量存储 线程是任务调度执行的最小单位

区别

1.进程是操作系统分配资源的单位,而线程是CPU任务执行和调度的单位;
2.进程是线程的容器,一个进程拥有一个或多个线程;
3.进程间的资源相互独立,进程间只能通过IPC进行通信,一个进程crash不会影响到其它进程;
4.同进程下的所有线程共享该进程的资源,线程间通信更方便但是付出代价保证线程安全。

并发:同一时间段,多个任务都在执行 (单位时间内不一定同时执行),分时调度(典型的调度方法:时间片轮转调度,每个任务可以得到一定的时间片执行,用完时间片则切换给另外的任务)

并行:单位时间内,多个任务同时执行(通常为多CPU或单CPU多核系统,允许多任务同时在不同CPU或不同核同时执行)

Android平台的进程&线程

Android基于Linux内核而又选择使用Java作为应用开发语言,周知的Java之所以应用的这么广泛--->由于JVM的存在隐藏的不同平台硬件的差异,java程序都运行在JVM中。

//从一句最简单的执行java程序的指令,可以看到需要先调用java命令起一个jvm实例,然后jvm的类加载器将test.class加载解析运行
javac test.java && java test 

Android看中了java的跨平台特性,所以Android应用程序也是不可避免的跑在VM上,当Java程序或者Android应用程序运行的时候没有一个虚拟机是无辜的。

Google公司自己设计实现了用于Android平台的Dalvik虚拟机以及对应的dex格式,适合于内存和处理器速度有限的系统。以及后续由使用ART替代了Dalvik。(三类VM之间的具体差异参考:Android开发——JVM、Dalvik以及ART的区别

每一个Android应用程序(进程)都运行在一个DVM or ART虚拟机实例中, Dalvik虚拟机进程就是本地操作系统进程,也就是Linux进程,区别在于前者运行有一个Dalvik虚拟机实例。这个虚拟机负责对象的生命周期、堆栈内存管理、垃圾回收&线程管理等。
具体分析可以看:https://blog.csdn.net/sauphy/article/details/50507593

Android的线程基本就是Thread、Handler、MessageQueue&Looper这相爱相杀的一套。

Android的多进程

多进程的使用方式:

AndroidMantifest.xml中的activity、service、receiver和provider均支持android:process属性; application元素也支持android:process属性,可以修改应用程序的默认进程名(默认值为包名)

开启私有进程:android:process=":processName",以冒号开头,最终进程名为packageName:processName com.baidu.searchbox:bdservice_v1

开启全局进程:android:process="com.example.processtest.remote"
其他应用通过设置相同的ShareUID可以和它跑在同一个进程达到文件数据资源共享的目的

使用方法很简单,但是首先来聊聊为啥要使用多进程?
笔者个人总结可能有这么些理由:

1.进程或者说应用保活,更合适的说法是让自己的应用有合适的进程优先级;
2.消耗内存的大的应用更合理的使用资源;
3.超级App(包含很多功能模块的应用)合理使用更多资源并且增强应用的稳定性

让应用拥有合适的进程优先级

在Android生态野蛮生长期,特别是国内经常Native守护进程的方案经常被用来作后台保活;在后续5.0之后Google慢慢整改收回多数权限封堵漏洞,这种情况得以改善。
笔者更倾向于使用多进程,设定合适的优先级既能实现自己应有的合理保活又符合Google的规范保证Android的生态健康。

1.前台进程
2.可见进程
3.服务进程
4.后台进程
5.空进程

规范使用进程优先级:https://blog.csdn.net/qq_27489007/article/details/54377655

更合理的分配使用资源&稳定性

为了保证系统资源的平衡,Android手机厂商出厂会调整设定每个应用(进程)的堆内存上限ActivityManager.getMemoryClass()

    public int getMemoryClass() {
        return staticGetMemoryClass();
    }

    /** @hide */
    static public int staticGetMemoryClass() {
        // Really brain dead right now -- just take this from the configured
        // vm heap size, and assume it is in megabytes and thus ends with "m".
        String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", "");
        if (vmHeapSize != null && !"".equals(vmHeapSize)) {
            return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
        }
        return staticGetLargeMemoryClass();
    }

    /**
     * Return the approximate per-application memory class of the current
     * device when an application is running with a large heap.  This is the
     * space available for memory-intensive applications; most applications
     * should not need this amount of memory, and should instead stay with the
     * {@link #getMemoryClass()} limit.  The returned value is in megabytes.
     * This may be the same size as {@link #getMemoryClass()} on memory
     * constrained devices, or it may be significantly larger on devices with
     * a large amount of available RAM.
     *
     * <p>This is the size of the application's Dalvik heap if it has
     * specified <code>android:largeHeap="true"</code> in its manifest.
     */
    public int getLargeMemoryClass() {
        return staticGetLargeMemoryClass();
    }

    /** @hide */
    static public int staticGetLargeMemoryClass() {
        // Really brain dead right now -- just take this from the configured
        // vm heap size, and assume it is in megabytes and thus ends with "m".
        String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
    }

厂商出厂在/system/build.prop设定了:

dalvik.vm.heapstartsize=16m //应用默认初始堆大小
dalvik.vm.heapgrowthlimit=192m //最大堆增长上限,通常对应最大能使用的内存值

<application
        android:largeHeap="true">
dalvik.vm.heapsize=512m //若在Manifest声明了largeHeap="true" 则以这个值为最大内存上限

$adb shell getprop dalvik.vm.heapgrowthlimit
$adb shell getprop dalvik.vm.heapsize
$adb shell getprop dalvik.vm.heapstartsize

关于应用最大内存设定可参考文章:https://www.dazhuanlan.com/2020/02/28/5e58976696bfa/

由于进程最大内存使用是有上限的,所以若要使用开发一些内存消耗占用比较的应用,比如大图浏览编辑等;使用额外的进程可以在不影响正常业务进程的情况下获得多的内存来使用并且该进程异常crash也不会影响其它业务进程。

多进程的引发的问题

上面说了多进程使用可以获得的一些优势,那么需要付出的代价呢?

1.进程间资源独立隔离,那么单例、静态变量这些都会失效;
2.Application onCreate可能会调用多次;
3.进程间隔离,需要使用IPC才能通信,而不是线程间的Handler发发消息就能搞定了;
4.多进程下Sharepreference等文件读写并不安全

总之需要权衡实际需求来进行选择是否需要使用多进程,而不是为了多进程而多进程。

参考

1.https://blog.csdn.net/luoshengyang/article/details/8852432
2.https://blog.csdn.net/fanleiym/article/details/83894399

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容