【并发编程】程序的启动和终结

Android是一个多用户。多任务的系统。

同意多个app在同一时刻执行,在多个程序之间切换并不会有明显的延迟。

多任务是由Linux内核负责处理的,而程序的执行基于Linux进程。

Linux进程

Linux为每个用户分配一个唯一的用户ID(User ID)。用于区分不同的User。

由于权限的原因,每个用户仅仅能訪问私有资源。没实用户(除了Root用户,即超级管理员。我们这里不考虑这个用户。

)能够訪问其它用户的私有资源。因而,“沙盒”就用来独立这些用户。

在Android中。每个应用都有一个唯一的用户ID,也就是说,Android中的App相应着Linux中的用户,而且App之间不能互訪资源。

Android为每个进程都加入了一个Dalvik虚拟机,也就是每个app都相应一个Dalvik虚拟机。

下图展示了Linux进程。Dalvik虚拟机和App之间的关系。

默认,App和进程有一对一的关系。

但假设有须要的话。一个App能够在几个进程中执行,或者几个App在同一个进程中执行。

生命周期

App的生命周期被封装在它自己的Linux进程中。从Java的视角来说,就是android.app.Application类。

当Dalvik调用Application的onCreate()方法时,Applicationg对象就被生成了。

理想情况下。Dalvik调用Application的onTerminate()的时候,app就停止了。

但切记,不能依靠这个去推断一个Application对象被销毁了!

由于潜在的Linux进程也许已经被Kill掉了,这个时候Dalvik还没有调用onTerminate()。

总之,Application对象是在一个进程中第一个被实例化的对象。也是最后一个被销毁的。

App启动

当一个App的不论什么一个组件被激活的时候,这个App就被开启了。

不论什么组件都是App的入口。

还记得吗,组件包含:Activity,BroadcastReceiver,Service和ContentProvider。

当第一个组件被激活的时候,这个App的Linux进程就被激活了,除非这个Linux进程已经处于执行状态。

App开启的过程总结例如以下:

  1. 开启Linux进程.
  2. 创建Dalvik虚拟机.
  3. 创建Application实例.
  4. 创建App的入口组件.

建立一个新的Linux进程和Dalvik虚拟机并非一个瞬时的操作。这个过程会减少性能,而且对用户体验稍有影响。

因此,Linux系统通过在启动(系统启动)的时候开启一个特别的Zygote进程去缩短App的启动时间。

这是怎么回事呢。Zygote包含了全部预载入的核心库。新的App进程就是从这个Zygote进程孵化出来的,可是App进程并不会复制那些预载入的核心库,而是共用Zygote的核心库。

就是这样。缩短了App的启动时间。

App终结

在App启动的时候,Linux进程被创建,当系统须要回收资源的时候Linux进程终结。为了保证用户每次进入App时不会反复上面的流程。假设不是真的到了资源缺的地步,Dalvik是不会销毁这个App的全部资源的。因此,虽然一个App的全部组件都被销毁了。这个App也不会自己主动终结。

当系统处于资源紧缺的时候,Dalvik负责决定哪一个进程要被Kill掉。那究竟是基于什么去决定是哪一个进程呢?

基于App的可见性和它的组件执行情况。系统对进程进行分级处理。也就是说,低级别进程在高级别进程之前被Kill掉。

以下是进程的各个级别:

Foreground
App在前台有可见的组件,或者有一个Service与其它进程中的某个可见的Activity处于绑定状态,或者BroadcastReceiver正在执行。
Visible
App有一个部分可见的组件。
Service
Service处于执行状态。可是并没有和一个可见的组件绑定。
Background
不可见的Activity。
Empty
没有活跃组件的进程。

空进程之所以存在,就是为了改善App的启动次数,可是它们也会第一个被Kill掉。

參考资料

http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle

时间: 2024-10-29 03:09:26

【并发编程】程序的启动和终结的相关文章

Android 并发编程:(一)基础知识 —— 1.2 程序的启动和终结

本章节所有内容皆为原创,如需转载,请注明出处. http://blog.csdn.net/manoel/article/details/38471825 Android是一个多用户,多任务的系统. 允许多个app在同一时刻执行,在多个程序之间切换并不会有明显的延迟. 多任务是由Linux内核负责处理的,而程序的运行基于Linux进程. Linux进程 Linux为每一个用户分配一个唯一的用户ID(User ID),用于区分不同的User. 因为权限的原因,每一个用户只能访问私有资源,没有用户(除

高级程序员需知的并发编程知识(二)

说明 本篇是继上一篇并发编程未讨论完的内容的续篇.上一篇传送门: Java并发编程一万字总结(吐血整理) 活跃性问题 在上一篇我们讨论并发编程带来的风险的时候,说到其中 一个风险就是活跃性问题.活跃性问题其实就是我们的程序在某些场景或条件下执行不下去了.在这个话题下我们会去了解什么是死锁.活锁以及饥饿,该如何避免这些情况的发生. 死锁 我们一般使用加锁来保证线程安全,但是过度地使用加锁,可能导致死锁发生. 哲学家进餐问题 "哲学家进餐"问题能很好地描述死锁的场景.5个哲学家去吃火锅,坐

Java 并发编程之图形界面应用程序及死锁问题

不知道为什么这本书还要讲一个界面应用程序,Java的界面做的很糟糕,效率低下,而且界面是java的弱项,可能是因为这里边是有一些并发编程的知识吧. 为什么GUI是单线程的 无论是Swing还是AWT都是单线程的.但它不仅限于在java中,在Qt,NexiStep,macOs CoCoa X windows以及其它环境中的GUI框架都是单线程的,许多人都曾经尝试编写多线程的GUI框架,但最终都由于竞态条件和死锁导致的稳定性问题而又重新回到单线程的事件队列模型:采用一个专门的线程从队列中抽取事件,并

【VC编程技巧】窗体?3.5对单文档或者多文档程序制作启动画面

(一)概要: 文章描述了怎样通过Visual C++ 2012或者Visual C++ .NET,为单文档或者多文档程序制作启动画面.在Microsoft Visual Studio 6.0中对于单文档程序(SDI)我们可以很方便利用微软提供的组件Visual C++ Component (Splash Screen).因为在Microsoft Visual Studio 6.0以后的版本或者Visual C++ .NET没有提供这个组件,我们可以通过自定义对话框来实现Splash Screen

IOS编程教程(八):在你的应用程序添加启动画面

IOS编程教程(八):在你的应用程序添加启动画面 虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些新学代码的人,可能没有听说过“闪屏”把,让我先作一个简单的解释.闪屏是常见于iOS应用程序,以及其他桌面应用程序.这是你启动一个应用程序时,你看到的第一个画面.通常情况下,初始屏幕是一个覆盖整个屏幕的图像,消失后加载主屏幕.下图显示了几种闪屏: 简单闪屏(开始页面) 闪屏的主要目的是为了让用户知道你的程

MFC之窗口修改工具栏编程状态栏编程程序启动画面

1窗口外观的修改 (1)修改在CMainFrame::preCreateWindow(CREATESTRUCT& cs) 修改标题:cs.style&=FWS_ADDTOTITLE; cs.lpszNamw="new title"; (2)窗口创建之后修改外观 在CMainframe::Create()中调用SetWindowLong(HWND hwnd,.....)根据参数修改指定的项 所有从CWnd派生的类都是窗口类在这些窗口类中都有一个公有的成员变量保存了和着个窗

Java并发编程之线程创建和启动(Thread、Runnable、Callable和Future)

这一系列的文章暂不涉及Java多线程开发中的底层原理以及JMM.JVM部分的解析(将另文总结),主要关注实际编码中Java并发编程的核心知识点和应知应会部分. 说在前面,Java并发编程的实质,是线程对象调用start方法启动多线程,而线程对象则必须是Thread类或其子类实现.Runnable和Callable的作用类似于Comparable.Serializable,是用于被并发的类实现的接口,从而使得Thread类可以在初始化时传入这个被并发的类.此是大前提.本文从多线程实现和启动出发,对

[Java并发编程实战]构建一个高效可复用缓存程序(含代码)

[Java并发编程实战]构建一个高效可复用缓存程序(含代码) 原文地址:https://www.cnblogs.com/chengpeng15/p/9915800.html

VC++编程中为程序加入启动画面功能

 如何为自己的程序加入启动画面 观察我们平常使用的软件,当我们双击软件的时候,会在主界面出现前,先行出现一个启动画面,由于前一阵子写了一个基于对话框的程序,亲自实验了下,今天就为大家简单的介绍下,在我们的程序中如何实现增加启动画面的功能. 在这里说明说明一下,我们平常使用的编译器是VS2010 或者是VS2012,在早一点的版本中,例如vc6.0中,加入启动画面这一功能,编译器已经为我们封装好,我们直接使用他所提供的CSplashWnd类就行了.单击[Project\Add to Project