IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【安卓开机启动】安卓JVM加载so库流程 -> 正文阅读

[移动开发]【安卓开机启动】安卓JVM加载so库流程

安卓JVM加载so库流程

好久没有写点东西发了,工作中的事情有点杂,也找不到整块东西可以写的。

最近调查了一个问题,稍微追了一下流程,这里记录一下。

1. 问题背景

由于我们支持的设备相对比竞品,zygote进程多占用了好几倍的内存空间。通过dump meminfo后发现,我们的设备在so库,ttf,和unkonwn mmap的内存空间相比竞品一共大了20多M,其中so库多了15M左右。

通过查看zygote进程的smaps,确定了占用空间最大的几个so库确实是我们自己的。虽然确定了内存占用大的原因,还是得把这些so库是加载在zygote进程中的时机确定了才行。

我的第一反应就是在zygote启动时,加载sharedLibrary()时,把这些库加载了,于是去看了这部分源码,并没有。

通过反复调试以及追踪源码,最后发现是在JVM启动的过程中加载了这些so库,这些so库的配置在“system/etc/public.libraries.txt”下。

在这里插入图片描述

这个文件里配置的都是public的so库,能够被普通app访问的。类似的配置文件还有“vendor/etc/”下面的,还有一些其他的配置地方,我没有深入去看,想要看的盆友可以自己去看源码或者注释。

下面我就带大家一起看看虚拟机加载这些so库的流程。

2. JVM加载so库流程

调用栈:

frameworks/base/cmds/app_process/app_main.cpp

? ---->runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);

frameworks/base/core/jni/AndroidRuntime.cpp

? ---->AndroidRuntime::startVm

? —>JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs)

art/runtime/jni/java_vm_ext.cc

? —>android::InitializeNativeLoader();

system/core/libnativeloader/native_loader.cpp

? ---->Initialize()

? ---->ReadConfig(public_native_libraries_system_config, &sonames, always_true, &error_msg)

其中,public_native_libraries_system_config 为 system/etc/public.libraries.txt

这部分流程是在安卓设备开机过程中的,在执行ZygoteInit.main()之前会先启动java虚拟机的,这样fork其他java进程的时候,java环境就已经有了,不用再创建虚拟机了。

最后贴一下Initialize()函数:

void Initialize() {
//一旦public命名空间被初始化,运行这个代码就没有意义了——它对当前的public库列表没有任何影响。
    if (initialized_) {
      return;
    }

    std::vector<std::string> sonames;
    const char* android_root_env = getenv("ANDROID_ROOT");
    std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
    std::string public_native_libraries_system_config =
            root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
    std::string llndk_native_libraries_system_config =
            root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
    std::string vndksp_native_libraries_system_config =
            root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;

    std::string product_public_native_libraries_dir = "/product/etc";

    std::string error_msg;
    LOG_ALWAYS_FATAL_IF(
        !ReadConfig(public_native_libraries_system_config, &sonames, always_true, &error_msg),
        "Error reading public native library list from \"%s\": %s",
        public_native_libraries_system_config.c_str(), error_msg.c_str());

//对于可调试的平台构建,使用ANDROID_ADDITIONAL_PUBLIC_LIBRARIES环境变量将库添加到列表中。这仅用于平台测试。
    if (is_debuggable()) {
      const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
      if (additional_libs != nullptr && additional_libs[0] != '\0') {
        std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
        std::copy(additional_libs_vector.begin(), additional_libs_vector.end(),
                  std::back_inserter(sonames));
      }
    }

//删除运行时命名空间中的公共库。这些库列在public.android.txt中,但我们不希望android的其余部分在默认命名空间中打开这些库。
      //例如,libicuuc。因此从运行时名称空间公开给类装入器名称空间。
      //不幸的是,它没有稳定的C符号,并且默认的命名空间应该只在libandroidicus .so中使用稳定的符号。http://b/120786417
    removePublicLibsIfExistsInRuntimeApex(sonames);

    // android_init_namespaces()期望加载所有的公共库,以便仅通过soname找到它们。
    // TODO(迪米特里·):这有点误导,因为我们不知道供应商公共库是否将从 /vendor/lib打开,我们可能最终会从/system/lib或/product/lib加载它们
      
    for (const auto& soname : sonames) {
      LOG_ALWAYS_FATAL_IF(dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr,
                          "Error preloading public library %s: %s", soname.c_str(), dlerror());
    }

    system_public_libraries_ = base::Join(sonames, ':');

    // read /system/etc/public.libraries-<companyname>.txt which contain partner defined
    // system libs that are exposed to apps. The libs in the txt files must be
    // named as lib<name>.<companyname>.so.
    sonames.clear();
    ReadExtensionLibraries(base::Dirname(public_native_libraries_system_config).c_str(), &sonames);
    oem_public_libraries_ = base::Join(sonames, ':');

    // read /product/etc/public.libraries-<companyname>.txt which contain partner defined
    // product libs that are exposed to apps.
    sonames.clear();
    ReadExtensionLibraries(product_public_native_libraries_dir.c_str(), &sonames);
    product_public_libraries_ = base::Join(sonames, ':');

    // Insert VNDK version to llndk and vndksp config file names.
    insert_vndk_version_str(&llndk_native_libraries_system_config);
    insert_vndk_version_str(&vndksp_native_libraries_system_config);

    sonames.clear();
    ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
    system_llndk_libraries_ = base::Join(sonames, ':');

    sonames.clear();
    ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
    system_vndksp_libraries_ = base::Join(sonames, ':');

    sonames.clear();
    // This file is optional, quietly ignore if the file does not exist.
    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames, always_true, nullptr);

    vendor_public_libraries_ = base::Join(sonames, ':');
  }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:12:56  更:2022-03-06 13:13:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:16:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码