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的别名)

[转]Native进程的运行过程的更多相关文章

  1. 详细理解Java虚拟机的运行过程

    基本概述: Java虚拟机简称JVM,是JRE中的一部分,也是Java程序运行的最关键的部分.完整的Java运行流程大致包括编译.java文件形成.class文件,然后根据.class文件的内容进行一 ...

  2. linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程

    1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...

  3. Linux内核分析——理解进程调度时机跟踪分析进程调度与进程切换的过程

    20135125陈智威 +原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验 ...

  4. Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程

    一.原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O:通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型:需要大量的CPU时间进 ...

  5. 20135202闫佳歆--week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程--实验及总结

    week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程 1.环境搭建: rm menu -rf git clone https://github.com/megnning/menu.gi ...

  6. windows进程/线程创建过程 --- windows操作系统学习

    有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...

  7. 通过gdb跟踪进程调度分析进程切换的过程

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本实验目的:通过gdb在lin ...

  8. android的编译和运行过程深入分析

    android的编译和运行过程深入分析 作者: 字体:[增加 减小] 类型:转载 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,此过程对了解android的编译和运 ...

  9. Android4.4 Framework分析——Zygote进程的启动过程

    Android启动过程中的第一个进程init.在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote. 本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门 ...

随机推荐

  1. 常用模块(chardet)

    作用:检测二进制的编码格式,不是百分百正确 import chardet f = open('test.txt', 'rb')data = f.read()print(data)result = ch ...

  2. 在ubuntu下 使用Jetty 和 Maven 开发 HelloWorld

    1 安装JDK 我以前安装过,这里就不说了. 2 安装maven 去官网下载 解压 添加环境变量   gedit ~/.bashrc export JETTY_HOME=/home/roc/libs/ ...

  3. python学习笔记-list的用法

    1.list的定义 list = [] list = [1,2,'a','b'](list中的元素不一定是一个类型) 2.list的操作 1)list.append(value) 2)list.ins ...

  4. penLDAP学习笔记

    LDAP协议 目录是一组具有类似属性.以一定逻辑和层次组合的信息.常见的例子是通讯簿,由以字母顺序排列的名字.地址和电话号码组成.目录服务是一种在分布式环境中发现目标的方法.目录具有两个主要组成部分: ...

  5. js把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式

    最近在做项目的时候,需要把后台返回的时间转换成几秒前.几分钟前.几小时前.几天前等的格式:后台返回的时间格式为:2015-07-30 09:36:10,需要根据当前的时间与返回的时间进行对比,最后显示 ...

  6. spring MVC 字符串数组传值 字符带有逗号,问题

    按照如下图所示方式传值,想在后台得到一个长度为1的数组,后台直接根据,进行分割,就得到长度为2的数组 1.曲线救国解决法 解决方案, 前端对参数进行编码 encodeURIComponent(valu ...

  7. 为Ubuntu安装SSH服务

    只有当Ubuntu安装了SSH服务后,我们才能够通过ssh工具登陆Ubuntu.我自己喜欢使用x-shell作为终端工具 1.安装Ubuntu缺省安装了openssh-client,所以在这里就不安装 ...

  8. 【bzoj2659】[Beijing wc2012]算不出的算式 数论

    题目描述 求,其中p和q是奇质数. 输入 只有一行,两个奇质数,分别表示p,q. 输出 一个数,表示算式结果. 样例输入 5 样例输出 6 题解 数论 神TM数学结论题... 当$p\neq q$时, ...

  9. IIS 发布后无法连接数据库(应用池问题)

    查找网站对应的  应用池,修改为 .net4.0  然后设置启动32位应用程序为 True

  10. POJ 3693 Maximum repetition substring(最多重复次数的子串)

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10461   Ac ...