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字节码)而引起的。

er

上图中,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的别名)

最新文章

  1. mysql5.7密码问题
  2. JAVA中精确计算金额BigDecimal
  3. 使用dynamic获取类型可变的json对象
  4. springmvc web应用程序 java
  5. Spring入门之HelloSpring
  6. C# 中的枚举类型 enum (属于值类型)
  7. WIN7下使用.net(C#)监视剪贴板 (转)
  8. Android源码之Gallery专题研究(2)
  9. Windows定时计划执行Python
  10. 代码托管SVN到Git迁移(使用小乌龟工具)
  11. web网络协议
  12. git常用命令值stash
  13. JS设置Cookie过期时间
  14. Mysql集群原理
  15. Rman常用命令
  16. python之Counter类:计算序列中出现次数最多的元素
  17. git使用操作
  18. STL中map的遍历
  19. 也谈谈Unity的transform使用
  20. FPGA设计中的float

热门文章

  1. bug单的提交
  2. PTA循环,函数,数组作业
  3. php获取微信token和ticket并返回签名
  4. BZOJ4560 JLOI2016字符串覆盖(kmp+贪心+状压dp+单调队列)
  5. perl的Sys::Syslog模块(openlog,syslog,closelog函数,setlogsock)-自定义日志
  6. 【题解】SHOI2008仙人掌图
  7. [洛谷P1951]收费站_NOI导刊2009提高(2)
  8. [NOIP2009]靶形数独 深搜+枝杈优化
  9. org.json与json-lib的区别(补充 FastJson)
  10. x:Class, x:Key