JNI_CreateJavaVM(Runtime::Create())

更新时间:2023-07-12 11:54:33 阅读: 评论:0

JNI_CreateJavaVM(Runtime::Create())
rvice zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-rver
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
前⾯的关键字rvice告诉init进程创建⼀个名为"zygote"的进程,这个zygote进程要执⾏的程序是/system/bin/app_process,后⾯是要传给app_process的参数。/frameworks/ba/cmds/app_process/app_main.cpp
泰州一百int main(int argc, char* const argv[])
{
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
// Everything up to '--' or first non '-' arg goes to the vm.
//
// The first argument after the VM args is the "parent dir", which
// is currently unud.
//
// After the parent dir, we expect one or more the following internal
/
/ arguments :
//
// --zygote : Start in zygote mode
// --start-system-rver : Start the system rver.
// --application : Start in application (stand alone, non zygote) mode.
// --nice-name : The nice name for this process.
//
// For non zygote starts, the arguments will be followed by
// the main class name. All remaining arguments are pasd to
// the main method of this class.
//
/
/ For zygote starts, all remaining arguments are pasd to the zygote.
// main function.
//
// Note that we must copy argument string values since we will rewrite the
// entire argument block when we apply the nice name to argv0.
int i;
for (i = 0; i < argc; i++) {
if (argv[i][0] != '-') {
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
}
// Par runtime arguments.  Stop at first unrecognized option.
bool zygote = fal;
bool startSystemServer = fal;
bool application = fal;
String8 niceName;
String8 className;
++i;  // Skip unud "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} el if (strcmp(arg, "--start-system-rver") == 0) {
startSystemServer = true;
} el if (strcmp(arg, "--application") == 0) {
application = true;
} el if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.tTo(arg + 12);
} el if (strncmp(arg, "--", 2) != 0) {
className.tTo(arg);
break;
} el {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
/
/ We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
//
// The Remainder of args get pasd to startup class main(). Make
// copies of them before we overwrite them with the process name.
args.add(application ? String8("application") : String8("tool"));
runtime.tClassNameAndArgs(className, argc - i, argv + i);
} el {
// We're in zygote mode.
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-rver"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
/
/ In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
runtime.tArgv0(niceName.string());
t_process_name(niceName.string());
食物中的营养物质}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args);
} el if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args);
} el {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}
/frameworks/ba/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{
/* start the virtual machine */
JniInvocation jni_invocation;
//load libart.so  初始化JniInvocation::JNI_CreateJavaVM_接⼝
jni_invocation.Init(NULL);磨砂膏有什么用
对口单招是什么意思JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) {
return;
}
onVmCreated(env);
/
*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/
* keep going */
} el {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} el {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
{
//JavaVM 参数配置
................
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
goto bail;
}
}
JniInvocation是单例类提供了3个接⼝,但是实际上真正⽤到的只有⼀个接⼝JNI_CreateJavaVM() class JniInvocation {
public:
JniInvocation();
~JniInvocation();
// Initialize JNI invocation API. library should specifiy a valid
// shared library for opening via dlopen providing a JNI invocation
// implementation, or null to allow defaulting via
// persist.sys.dalvik.vm.lib.
bool Init(const char* library);
// Expos which library is actually loaded from the given name. The
// buffer of size PROPERTY_VALUE_MAX will be ud to load the system
// property for the default library, if necessary. If no buffer is
// provided, the fallback value will be ud.
static const char* GetLibrary(const char* library, char* buffer);
private:
bool FindSymbol(void** pointer, const char* symbol);
static JniInvocation& GetJniInvocation();
jint JNI_GetDefaultJavaVMInitArgs(void* vmargs);
jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);
static JniInvocation* jni_invocation_;
void* handle_;
jint (*JNI_GetDefaultJavaVMInitArgs_)(void*);
jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*);
jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*);
friend jint JNI_GetDefaultJavaVMInitArgs(void* vm_args);
friend jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
friend jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);
};
JniInvocation::JniInvocation() :
handle_(NULL),
JNI_GetDefaultJavaVMInitArgs_(NULL),
JNI_CreateJavaVM_(NULL),
JNI_GetCreatedJavaVMs_(NULL) {
LOG_ALWAYS_FATAL_IF(jni_invocation_ != NULL, "JniInvocation instance already initialized");
jni_invocation_ = this;
}
//加载libart.so
bool JniInvocation::Init(const char* library) {
#ifdef HAVE_ANDROID_OS
char buffer[PROPERTY_VALUE_MAX];
#el
char* buffer = NULL;
#endif
library = GetLibrary(library, buffer);
handle_ = dlopen(library, RTLD_NOW);
if (handle_ == NULL) {
if (strcmp(library, kLibraryFallback) == 0) {
// Nothing el to try.
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return fal;
}
// Note that this is enough to get something like the zygote
// running, we can't property_t here to fix this for the future
// becau we are root and not the system ur. See
// Init for where we fix up the property to
// avoid future fallbacks. b/11463182
ALOGW("Falling back from %s to %s after dlopen error: %s",
library, kLibraryFallback, dlerror());
library = kLibraryFallback;
handle_ = dlopen(library, RTLD_NOW);
if (handle_ == NULL) {
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return fal;
}
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {
return fal;
}
//给函数指针JNI_CreateJavaVM_赋值
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return fal;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) {
return fal;
}
return true;
}
jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
//调⽤动态加载的函数指针
return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}
bool JniInvocation::FindSymbol(void** pointer, const char* symbol) {
*pointer = dlsym(handle_, symbol);
if (*pointer == NULL) {
ALOGE("Failed to find symbol %s: %s\n", symbol, dlerror());
dlclo(handle_);
handle_ = NULL;
return fal;
}
return true;
小于等于符号
}
// 实现jni.h中的JNI_CreateJavaVM⽅法
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);
}
.....................
libart.so中的⽅法在Jni_internal中实现
FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_), "JNI_CreateJavaVM" //Jni_internal
// JNI Invocation interface.
extern"C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
if (IsBadJniVersion(args->version)) {
LOG(ERROR) << "Bad JNI version pasd to CreateJavaVM: " << args->version;
return JNI_EVERSION;
}
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;
if (!Runtime::Create(options, ignore_unrecognized)) {
return JNI_ERR;
}
Runtime* runtime = Runtime::Current();
bool started = runtime->Start();
if (!started) {
delete Thread::Current()->GetJniEnv();
delete runtime->GetJavaVM();
LOG(WARNING) << "CreateJavaVM failed";
return JNI_ERR;
}
*p_env = Thread::Current()->GetJniEnv();
*p_vm = runtime->GetJavaVM();
return JNI_OK;
}
extern"C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
Runtime* runtime = Runtime::Current();
if (runtime == nullptr) {
*vm_count = 0;
} el {
*vm_count = 1;
vms[0] = runtime->GetJavaVM();
}
return JNI_OK;
}
// Historically unsupported.
extern"C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
return JNI_ERR;
}
很明显,除了JNI_CreateJavaVM(),另外两个⽅法没什么作⽤
中概股是什么
/art/runtime/jni_internal
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
// 第⼀⼤步:创建Runtime
if (!Runtime::Create(options, ignore_unrecognized)) {
return JNI_ERR;
}
Runtime* runtime = Runtime::Current();
// 第⼆⼤步:Runtime::start()
bool started = runtime->Start();
if (!started) {
delete Thread::Current()->GetJniEnv();
delete runtime->GetJavaVM();
LOG(WARNING) << "CreateJavaVM failed";
return JNI_ERR;
}
*p_env = Thread::Current()->GetJniEnv();
*p_vm = runtime->GetJavaVM();
return JNI_OK;
}
instance_是Runtime类的静态成员变量,它指向进程中的⼀个Runtime单例。这个Runtime单例描述的就是当前进程的ART虚拟机实例。class Runtime {
static Runtime* instance_;
InstructionSet instruction_t_;
bool is_zygote_;
bool must_relocate_;
bool is_concurrent_gc_enabled_;
bool is_explicit_gc_disabled_;
bool dex2oat_enabled_;
bool image_dex2oat_enabled_;
std::string boot_class_path_string_;
斯卡布罗集市简介std::string class_path_string_;
gc::Heap* heap_;
ThreadList* thread_list_;
InternTable* intern_table_;
ClassLinker* class_linker_;
JavaVMExt* java_vm_;
// A non-zero value indicates that a thread has been created but not yet initialized. Guarded by
/
/ the shutdown lock so that threads aren't born while we're shutting down.
size_t threads_being_born_ GUARDED_BY(Locks::runtime_shutdown_lock_);
}
/art/runtime/runtime
bool Runtime::Create(const RuntimeOptions& options, bool ignore_unrecognized) {
// Runtime是单例,只会被初始化⼀次
if (Runtime::instance_ != NULL) {
return fal;
}
//这个log初始化需要⼀点点时间,这个时候LOG(TAG)是打印不出来的
InitLogging(NULL);  // Calls Locks::Init() as a side effect.
instance_ = new Runtime;
if (!instance_->Init(options, ignore_unrecognized)) {
delete instance_;
instance_ = NULL;
return fal;
}
return true;
}
bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
MemMap::Init();
/
/解析Andriod VM的配置参数
std::unique_ptr<PardOptions> options(PardOptions::Create(raw_options, ignore_unrecognized));
if (() == nullptr) {
LOG(ERROR) << "Failed to par options";
return fal;
}
VLOG(startup) << "Runtime::Init -verbo:startup enabled";
QuasiAtomic::Startup();
Monitor::Init(options->lock_profiling_threshold_, options->hook_is_nsitive_thread_);
// boot_class_path_string_ =
/
/ /system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:
// /system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:
// /system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:
// /system/framework/apache-xml.jar:/system/framework/HtcLegacy.jar:/system/framework/mediatek-common.jar:/system/framework/mediatek-framework.jar:
// /system/framework/mediatek-telephony-common.jar:/system/framework/dolby_ds.jar
boot_class_path_string_ = options->boot_class_path_string_;
class_path_string_ = options->class_path_string_;
properties_ = options->properties_;
compiler_callbacks_ = options->compiler_callbacks_;
patchoat_executable_ = options->patchoat_executable_;
must_relocate_ = options->must_relocate_;
is_zygote_ = options->is_zygote_;
is_explicit_gc_disabled_ = options->is_explicit_gc_disabled_;
dex2oat_enabled_ = options->dex2oat_enabled_;
image_dex2oat_enabled_ = options->image_dex2oat_enabled_;
vfprintf_ = options->hook_vfprintf_;
exit_ = options->hook_exit_;
abort_ = options->hook_abort_;
default_stack_size_ = options->stack_size_;
stack_trace_file_ = options->stack_trace_file_;
compiler_executable_ = options->compiler_executable_;
compiler_options_ = options->compiler_options_;
image_compiler_options_ = options->image_compiler_options_;
image_location_ = options->image_;
max_spins_before_thin_lock_inflation_ = options->max_spins_before_thin_lock_inflation_;  monitor_list_ = new MonitorList;
monitor_pool_ = MonitorPool::Create();
thread_list_ = new ThreadList;
intern_table_ = new InternTable;
verify_ = options->verify_;
if (options->interpreter_only_) {
GetInstrumentation()->ForceInterpretOnly();
}
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_pau_log_threshold_,
options->long_gc_log_threshold_,
options->ignore_max_footprint_,
options->u_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->u_homogeneous_space_compaction_for_oom_,
options->min_interval_homogeneous_space_compaction_by_oom_);
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.
// 加载如下两个库:
// dlsym(RTLD_NEXT, "sigaction");
// dlsym(RTLD_DEFAULT, "sigprocmask");
InitializeSignalChain();
if (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_) {
//所有信号都要交给fault_manager来处理,所以这个很早就初始化了
fault_manager.Init();
// The need to be in a specific order.  The null point check handler must be
// after the suspend check and stack overflow check handlers.
if (implicit_suspend_checks_) {  //fal
suspend_handler_ = new SuspensionHandler(&fault_manager);
}
if (implicit_so_checks_) {    //true
stack_overflow_handler_ = new StackOverflowHandler(&fault_manager);
}
if (implicit_null_checks_) {  //ture
null_pointer_handler_ = new NullPointerHandler(&fault_manager);
}
if (kEnableJavaStackTraceHandler) {  //fal
new JavaStackTraceHandler(&fault_manager);
}
}
java_vm_ = new JavaVMExt(this, ());
Thread::Startup();
// ClassLinker needs an attached thread, but we can't fully attach a thread without creating  // objects. We can't supply a thread group yet; it will be fixed later. Since we are the main  // thread, we do not get a java peer.
Thread* lf = Thread::Attach("main", fal, nullptr, fal);
class_linker_ = new ClassLinker(intern_table_);
if (GetHeap()->HasImageSpace()) { //android虚拟机启动时,这⾥为真
class_linker_->InitFromImage();
if (kIsDebugBuild) {
GetHeap()->GetImageSpace()->VerifyImageAllocations();
}
} el {
.............
}
}
void Runtime::BlockSignals() {
SignalSet signals;
signals.Add(SIGPIPE);
// SIGQUIT is ud to dump the runtime's state (including stack traces).
signals.Add(SIGQUIT);
// SIGUSR1 is ud to initiate a GC.
signals.Add(SIGUSR1);
#if defined(HAVE_ANDROID_OS) && defined(MTK_DUMMY_PREDUMP)
signals.Add(SIGSTKFLT);
#endif
signals.Block();
}
//art/runtime/signal_t.h
class SignalSet {
public:
SignalSet() {
if (sigemptyt(&t_) == -1) {
失败英语
PLOG(FATAL) << "sigemptyt failed";
}

本文发布于:2023-07-12 11:54:33,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1078455.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:进程   单例   变量
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图