Android ART虚拟机 启动和初始化

Posted baiiu

tags:

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

前言

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

android Rumtime.cpp jni_internal.cc runtime.cc JNI_CreateJavaVM Runtime::Create Runtime::Init、new gc::Heap Runtime::Start Runtime::InitNativeMethods、StartDaemonThreads Android Rumtime.cpp jni_internal.cc runtime.cc

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) 

    // 拼接一大堆参数
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) 
        ALOGE("JNI_CreateJavaVM failed\\n");
        goto bail;
    

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);

jni_internal.cc

art/runtime/jni_internal.cc

extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) 
  const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);

  //  创建虚拟机
  if (!Runtime::Create(options, ignore_unrecognized)) 
    return JNI_ERR;
  
  Runtime* runtime = Runtime::Current();
  runtime->Start();

  *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) 
  Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);

  heap_ = new gc::Heap(options->heap_initial_size_,
                       options->heap_growth_limit_,
                       options->heap_min_free_,
                       options->heap_max_free_,
                       options->heap_target_utilization_,
                       options->foreground_heap_growth_multiplier_,
                       options->heap_maximum_size_,
                       options->heap_non_moving_space_capacity_,
                       options->image_,
                       options->image_isa_,
                       options->collector_type_,
                       options->background_collector_type_,
                       options->parallel_gc_threads_,
                       options->conc_gc_threads_,
                       options->low_memory_mode_,
                       options->long_pause_log_threshold_,
                       options->long_gc_log_threshold_,
                       options->ignore_max_footprint_,
                       options->use_tlab_,
                       options->verify_pre_gc_heap_,
                       options->verify_pre_sweeping_heap_,
                       options->verify_post_gc_heap_,
                       options->verify_pre_gc_rosalloc_,
                       options->verify_pre_sweeping_rosalloc_,
                       options->verify_post_gc_rosalloc_,
                       options->use_homogeneous_space_compaction_for_oom_,
                       options->min_interval_homogeneous_space_compaction_by_oom_);

  dump_gc_performance_on_shutdown_ = options->dump_gc_performance_on_shutdown_;

  BlockSignals();
  InitPlatformSignalHandlers();
  InitializeSignalChain();
  java_vm_ = new JavaVMExt(this, options.get());
  Thread::Startup();
  class_linker_ = new ClassLinker(intern_table_);
  //...
  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()) 
    ScopedObjectAccess soa(self);
    gc::space::ImageSpace* image_space = heap_->GetImageSpace();
    if (image_space != nullptr) 
      Runtime::Current()->GetInternTable()->AddImageStringsToTable(image_space);
      Runtime::Current()->GetClassLinker()->MoveImageClassesToClassTable();
    
  

  // InitNativeMethods needs to be after started_ so that the classes it touches will have methods linked to the oat file if necessary.
  InitNativeMethods();
  // Initialize well known thread group values that may be accessed threads while attaching.
  InitThreadGroups(self);

  Thread::FinishStartup();

  system_class_loader_ = CreateSystemClassLoader();

  StartDaemonThreads();

  finished_starting_ = true;
  return true;

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

Android ART虚拟机 启动和初始化

Dalvik虚拟机和Art虚拟机

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

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

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

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