Android ART虚拟机 启动和初始化

Posted baiiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ART虚拟机 启动和初始化相关的知识,希望对你有一定的参考价值。

前言

之前整理了一系列Dalvik虚拟机的关于堆内存和GC的文章,轮到对ART内存进行分析优化了,继续整理输出一波,本篇为ART虚拟机系列的第一篇,介绍ART虚拟机的启动和初始化。
本ART系列基于7.0代码分析。

ART启动

app_main启动

frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    if (zygote) 
        runtime.start("com.android.internal.os.ZygoteInit", args);
     else if (className) 
        runtime.start("com.android.internal.os.RuntimeInit", args);
     else 
        return 10;
    

AndroidRuntime.cpp

frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options)

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) 
        return;
    
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) 
        return;
    


int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)

    // JNI检测功能,用于native层调用jni函数时进行常规检测,比较弱字符串格式是否符合要求,资源是否正确释放。该功能一般用于早期系统调试或手机Eng版,对于User版往往不会开启,引用该功能比较消耗系统CPU资源,降低系统性能。
    bool checkJni = false;
    property_get("dalvik.vm.checkjni", propBuf, "");
    if (strcmp(propBuf, "true") == 0) 
        checkJni = true;
     else if (strcmp(propBuf, "false") != 0) 
        property_get("ro.kernel.android.checkjni", propBuf, "");
        if (propBuf[0] == '1') 
            checkJni = true;
        
    
    if (checkJni) 
        addOption("-Xcheck:jni");
    

    //虚拟机产生的trace文件,主要用于分析系统问题,路径默认为/data/anr/traces.txt
    parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");

    //对于不同的软硬件环境,这些参数往往需要调整、优化,从而使系统达到最佳性能
    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
    parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
    parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
    parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
    parseRuntimeOption("dalvik.vm.heaptargetutilization",
                       heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization=");
    ...

    //preloaded-classes文件内容是由WritePreloadedClassFile.java生成的,
    //在ZygoteInit类中会预加载工作将其中的classes提前加载到内存,以提高系统性能
    if (!hasFile("/system/etc/preloaded-classes")) 
        return -1;
    

    //初始化虚拟机,调用到JniInvocation
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) 
        return -1;
    

JniInvocation.cpp

libnativehelper/JniInvocation.cpp,
5.x的代码里获取libart.so,再获取到JNI_CreateJavaVM、JNI_GetCreatedJavaVMs等的实现。

static const char* kLibraryFallback = "libart.so";

bool JniInvocation::Init(const char* library) 
  library = GetLibrary(library, buffer);

  handle_ = dlopen(library, RTLD_NOW);
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
                  "JNI_GetDefaultJavaVMInitArgs")) 
    return false;
  
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
                  "JNI_CreateJavaVM")) 
    return false;
  
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
                  "JNI_GetCreatedJavaVMs")) 
    return false;
  
  return true;


extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) 
  return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);


extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) 
  return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);


extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) 
  return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);

java_vm_ext.cc

art/runtime/java_vm_ext.cc

extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) 
	// 虚拟机参数
  RuntimeOptions options;
  for (int i = 0; i < args->nOptions; ++i) 
    JavaVMOption* option = &args->options[i];
    options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
  
  bool ignore_unrecognized = args->ignoreUnrecognized;
  
  // 创建Runtime对象,它就是虚拟机的化身
  if (!Runtime::Create(options, ignore_unrecognized)) 
    return JNI_ERR;
  
  
  Runtime* runtime = Runtime::Current();
  // 启动runtime
  runtime->Start();
  
  // 获取JNI ENV和Java VM对象
  *p_env = Thread::Current()->GetJniEnv();
  *p_vm = runtime->GetJavaVM();
  
  return JNI_OK;

art初始化

art/runtime/runtime.h
art/runtime/runtime.cc

runtime.h

class Runtime 
 public:
  // Creates and initializes a new runtime.
  static bool Create(const RuntimeOptions& options, bool ignore_unrecognized)
      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
  // Starts a runtime, which may cause threads to be started and code to run.
  bool Start() UNLOCK_FUNCTION(Locks::mutator_lock_);
  static Runtime* Current() 
    return instance_;
  
  gc::Heap* GetHeap() const 
    return heap_;
  
  ~Runtime();

private:
  Runtime();
  void BlockSignals();
  bool Init(const RuntimeOptions& options, bool ignore_unrecognized)
      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
  // A pointer to the active runtime or NULL.
  static Runtime* instance_;
  gc::Heap* heap_;

Runtime::Create

bool Runtime::Create(const RuntimeOptions& options, bool ignore_unrecognized) 
  if (Runtime::instance_ != NULL) 
    return false;
  

  instance_ = new Runtime;
  instance_->Init(options, ignore_unrecognized);
  return true;

Runtime()

Runtime::Runtime()
    : is_zygote_(false),
      is_concurrent_gc_enabled_(true),
      is_explicit_gc_disabled_(false),
      dex2oat_enabled_(true),
      default_stack_size_(0),
      heap_(nullptr),
      monitor_list_(nullptr),
      monitor_pool_(nullptr),
      thread_list_(nullptr),
      class_linker_(nullptr),
      signal_catcher_(nullptr),
      java_vm_(nullptr) 

Runtime::Init

bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) 
	// MemMap模块,用于管理内存映射。
    // ART大量使用了内存映射技术,比如.oat文件
	MemMap::Init();

	// 锁实现,和Java中的monitor有关,用于实现线程同步的模块
    Monitor::Init(runtime_options.GetOrDefault(Opt::LockProfThreshold), runtime_options.GetOrDefault(Opt::HookIsSensitiveThread));
                
   	// 从raw_options转化为runtime_options,获取了n多参数
    ...
    
    // 维护了一组Monitor对象
    monitor_list_ = new MonitorList;
    // 用于创建Monitor对象
    monitor_pool_ = MonitorPool::Create();
    // 用于管理ART中的线程对象,Thread.cpp对象
    thread_list_ = new ThreadList;
    // 和string intern table有关,即字符串常量池
    intern_table_ = new InternTable;
    
    
    // heap,堆内存了
    heap_ = new gc::Heap(xxx);

		
    // 内存池类ArenaPool,可管理多个内存单元Arena
    const bool use_malloc = IsAotCompiler();
    arena_pool_.reset(new ArenaPool(use_malloc, false));
    
    // 内存分配器LinearAlloc,即可在ArenaPool上分配任意大小的内存
    if (IsCompiler() && Is64BitInstructionSet(kRuntimeISA)) 
      // 4gb, no malloc. Explanation in header.
      low_4gb_arena_pool_.reset(new ArenaPool(false, true));
      linear_alloc_.reset(new LinearAlloc(low_4gb_arena_pool_.get()));
     else 
      linear_alloc_.reset(new LinearAlloc(arena_pool_.get()));
    
    
    // 和信号处理有关,ART虚拟机进程需要截获来自操作系统的某些信号
    BlockSignals();
    // 为某些信号设置自定义的信号处理函数
    InitPlatformSignalHandlers();

    // Always initialize the signal chain so that any calls to sigaction get
    // correctly routed to the next in the chain regardless of whether we
    // have claimed the signal or not.
	InitializeSignalChain();
    
   	if (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_) 
    	// FaultManager,用于处理SIGENV信号
        fault_manager.Init();

		// 取值为false,启用隐式线程暂停thread suspension检查
        if (implicit_suspend_checks_) 
          new SuspensionHandler(&fault_manager);
        

		// 取值为true,启动隐式堆栈溢出
        if (implicit_so_checks_) 
          new StackOverflowHandler(&fault_manager);
        

		// 取值为true,启动隐式空指针检查
        if (implicit_null_checks_) 
          new NullPointerHandler(&fault_manager);
        

        if (kEnableJavaStackTraceHandler) 
          new JavaStackTraceHandler(&fault_manager);
        
  	
    
    // JavaVMExt是JNI中代表Java虚拟机的对象;
    // 根据JNI规范,一个进程只有唯一的一个JavaVM对象,对art虚拟机来说,这个JavaVm对象就是此处的java_vm
    java_vm_ = new JavaVMExt(this, runtime_options);
    
    // 调用Thread.cpp线程的Startup和Attach方法以初始化虚拟机主线程
    Thread::Startup();
    Thread* self = Thread::Attach("main", false, nullptr, false);
    
    // 处理和Class有关的工作,解析某个类、寻找某个类、加载某个类
    class_linker_ = new ClassLinker(intern_table_);
    
    // 用于检验Java方法的模块,类检验时会用
    verifier::MethodVerifier::Init();
    
    // 抛出OutOfMemoryError、NoClassDefFoundError,并清楚,可以理解成清空方法栈吧
    self->ThrowNewException("Ljava/lang/OutOfMemoryError;",
                            "OutOfMemoryError thrown while trying to throw OutOfMemoryError; "
                            "no stack trace available");
    pre_allocated_OutOfMemoryError_ = GcRoot<mirror::Throwable>(self->GetException());
    self->ClearException();
    self->ThrowNewException("Ljava/lang/NoClassDefFoundError;",
                            "Class not found using the boot class loader; no stack trace available");
    pre_allocated_NoClassDefFoundError_ = GcRoot<mirror::Throwable>(self->GetException());
    self->ClearException();

	return true;

runtime->start

bool Runtime::Start() 
  // Restore main thread state to kNative as expected by native code.
  Thread* self = Thread::Current();
  self->TransitionFromRunnableToSuspended(kNative);

  started_ = true;
  
  if (!IsZygote() && jit_options_->UseJIT()) 
  	// 加载JNI编译模块对应的so库
    CreateJit();
  
  
  // InitNativeMethods needs to be after started_ so that the classes
  // it touches will have methods linked to the oat file if necessary.
  // 初始化JNI层相关内容
  InitNativeMethods();
  
  // 完成Thread类初始化相关工作
  InitThreadGroups(self);
  Thread::FinishStartup();
  
  // 创建系统类加载器
  system_class_loader_ = CreateSystemClassLoader(this);
  
  // 启动虚拟机的daemon线程
  StartDaemonThreads();
  
  finished_starting_ = true;
  return true;

以上是关于Android ART虚拟机 启动和初始化的主要内容,如果未能解决你的问题,请参考以下文章

Android ART虚拟机 启动和初始化

Dalvik虚拟机和Art虚拟机

深入理解ART虚拟机—虚拟机的启动

深入理解ART虚拟机—ART的函数运行机制

深入理解ART虚拟机—ART的函数运行机制

Android内存优化DVM和ART原理初探