Native进程的运行过程

一般程序的启动步骤,可以用下图描述。程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行。

通常,native进程是由shell或者init启动,启动的过程如下:

  • Shell接收到命令,启动一个程序,此时shell首先会fork一个新的进程
  • 新fork的进程,通过execve系统调用,陷入到内核中,内核检查和加载需要执行的二进制映像文件,检验其合法性及权限。通常用户态进程要启动一个新的程序(如shell),fork后,execve要紧跟着执行,这样会有更好的效率(由于使用COW技术,这样可以避免页表复制,而execve后,之前进程中的所有内容都是无用的,若execve紧跟fork后,可以避免COW引起的拷贝);
  • 通常二进制文件都会要依赖一些系统动态库,此时kernel会启动加载器/system/bin/linker,执行linker的__linker_init()
  • Linker的linker_init(),会分析二进制的elf文件,加载依赖的动态库文件,然后转入二进制映像的入口函数__start中执行
  • __start会调用C库的初始化函数__libc_init()
  • __libc_init()会调用映像的main函数,这个main函数也就是用户app的入口函数
  • main() 函数执行完毕后,通过exit()退出进程执行

需要注意的是,android bionic提供的加载器是/system/bin/linker,而普通linux系统用的glibc是/lib/ld-linux-xx.so.2。这也是为何其他linux平台同指令架构的二进制文件,不能在android上运行的原因之一:启动用户进程的加载器这个程序运行的第一步就出错了。

Java进程的运行过程

Java进程的启动比较特殊,Java进程是zygote启动的,zygote在folk进程之后,并没有执行execve指令,因此是共享了zygote的代码段和数据段。其它的java进程,可以看做都是zygote的克隆,克隆之后的进程,各自根再据自己的需求(java代码),解释java语言。

也就是说:Android的所有进程,从native角度看都是zygote。 其对应的程序都是 /system/bin/app_process,虚拟机是运行在其中的。

那为何java进程又如此的不同呢? 实际上,从native的角度看,不同的各种java程序,可以如此理解:只是/system/bin/app_process 这个程序,因为不同的输入(Java dex字节码)而引起的。

上图中,user APK实际上市zygote的一个克隆(启动->进入main等之前的流程没有画出, app进程没有这个步骤,是从zygote进程中克隆过来),差别主要在dvm虚拟机执行的java代码的不同导致的表现的行为差异巨大。

Java进程没有执行exec调用,这样有一个很大的好处:使用linux的COW(copy on Write)技术,就可以在多个java进程间,共享内存资源——主要是java的核心库。

Java程序也可以使用native库,此时的native库需要通过dlopen来打开(即java中,使用System.loadLibrary()方法加载so库,虚拟机对应会调用的C库方法),dlopen加载so库的过程中,依旧会通过linker分析处理so库的elf信息,加载其它依赖的动态库。

(注:zygote实际上是/system/bin/app_process,zygote只是app_process的别名)

android app启动过程的更多相关文章

  1. android app启动过程(转)

    Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启 ...

  2. Zygote和System进程的启动过程、Android应用进程启动过程

    1.基本过程 init脚本的启动Zygote Zygote进程的启动 System进程的启动 Android应用进程启动过程 2.init脚本的启动 +------------+ +-------+ ...

  3. Android APP 调试过程中遇到的问题。

    调试过过程中APP安装完启动后有的时候会异常退出,报这个错误.有的时候可以直接启动.查找不到原因.网上说把commit方法替换成commitAllowingStateLoss() 也无效. Andro ...

  4. [FMX] Android APP 启动黑屏优化补丁

    使用说明 *************************************************** Android APP 启动黑屏优化补丁 作者: Swish, YangYxd 201 ...

  5. Android程序启动过程深入解析

    当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样的? 什么是Linux内核? 桌面系统linux内核与Android系统linux内核有什么区别? 什么是引导装载程序 ...

  6. Android app启动activity并调用onCreate()方法时都默默地干了什么?

    Android app启动activity并调用onCreate() 方法时都默默地干了什么?   在AndroidManifest.xml文件中的<intent-filter>元素中有这 ...

  7. android app启动就闪退怎么办?

    开发过程中,如遇到android app启动就闪退,不要急,直接进入调试模式运行app,就会取得出错的原因. http://blog.sina.com.cn/s/blog_44fa172f0102wg ...

  8. Android App 启动页(Splash)黑/白闪屏现象产生原因与解决办法(转)

    转载: Android App 启动页(Splash)黑/白闪屏现象产生原因与解决办法   首先感谢博主分享,本文作为学习记录 惊鸿一瞥 微信的启动页,相信大家都不陌生. 不知道大家有没有发现一个现象 ...

  9. wxWidgets源码分析(1) - App启动过程

    目录 APP启动过程 wxApp入口定义 wxApp实例化准备 wxApp的实例化 wxApp运行 总结 APP启动过程 本文主要介绍wxWidgets应用程序的启动过程,从app.cpp入手. wx ...

随机推荐

  1. eclipse选中某个字段没法高亮其他相同字段

    eclipse选中某个字段无法高亮其他相同字段解决办法: window >> preference >> java >> Editor >> Mark ...

  2. windows 10 下配置安装node.js

      环境配置 node.js windows10 25.5k 次阅读  ·  读完需要 6 分钟 5 在去年就自己配置安装过node.js,但是使用npm安装模块时安装成功后调用require('mo ...

  3. python之函数2

    Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  4. javascript变量浅析

    变量声明 javascript 使用var + 变量名 声明变量,因为javascript是弱类型语言, 所有我们可以随意更改已有变量的类型. var b=1; b='2', 另外不同于c#中的var ...

  5. 【C#】简单的发送socket字符串

    1 打开VS,新建一个C#窗口程序 2 添加按钮 3 写按钮的事件代码 双击这个按钮 进入代码界面 输入如下内容,注意IP和端口 private void button1_Click(object s ...

  6. dotNet Core WEB程序使用 Nginx反向代理

    之前记录过一篇 使用 jexus 作为dotNetCore的反向代理,发现jexus的内存占用较大,最终选择使用Nginx的原因就是占用内存较小,以及性能较优(https://www.cnblogs. ...

  7. ASP.NET MVC 导入Excel文件

    一:view部分 <form method="post" enctype="multipart/form-data" action="/Posi ...

  8. 【五校联考3day2】C

    題意: 現有一平面直角坐標系,有n個點,每一個點必須向某一個方向發射射線,且任意一條射線必須與某一條坐標軸平行.定義一種發射射線的方案是合法的,則方案必須滿足: 1.沒有一條射線交叉 2.沒有一條射線 ...

  9. 百度地图sdk---pc端

    <div class="map" style="width: 1196px;height: 500px;margin: 50px auto;"> & ...

  10. sed 横排扩展

    sed "$!N;s/\n/KEY/" FILENAME