Hotspot源码解析-第26章-初始化时调用Java系统类的必要的方法
第26章-初始化时调用Java系统类的必要的方法
这一章主要为Java执行前预设必要的环境,需要调用的Java系统类的一些必要的方法,预设环境包括:为Java环境设置系统属性、设置输入输出及错误输出环境、获取并初始化Java系统加载器(也就是AppClassLoader)等,这里就不一一列出,接下来的源码解析会把这些过程都列出。
调用入口还是在thread.cpp->create_vm()
初始化 System 类
thread.cpp->call_initializeSystemClass(CHECK_0)
static void call_initializeSystemClass(TRAPS) {
// 拿到 System 类对应的Klass
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
// 转成句柄
instanceKlassHandle klass (THREAD, k);
// 定义返回结果对象
JavaValue result(T_VOID);
/* 这里就去调用Java方法了,调用的是 java/lang/System 的 initializeSystemClass_name 名字 对应的方法,
* 这块 对应关系在vmSymbols.hpp中定义:
* template(initializeSystemClass_name, "initializeSystemClass")
* 既然是调用Java的方法,那么接下来就要转到Java代码了,继续往下看
*/
JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(),
vmSymbols::void_method_signature(), CHECK);
}
System.initializeSystemClass()
接下来都是 Java 代码,就不一行行给大家解读了,直接描述意思就行
private static void initializeSystemClass() {
// 看着是不是很熟悉,就是把系统属性内容设置到props中
props = new Properties();
initProperties(props); // initialized by the VM
// 保存并移除一些属性
sun.misc.VM.saveAndRemoveProperties(props);
// 行分隔符
lineSeparator = props.getProperty("line.separator");
sun.misc.Version.init();
// 输入、输出、错误输出设置
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
// 现在加载 zip 库,可避免 java.util.zip.ZipFile 后续尝试使用自身来加载此库
loadLibrary("zip");
// 在 HUP、TERM 和 INT(如果可用)上设置 Java 信号处理程序
Terminator.setup();
// 初始化需要用到的操作系统环境
sun.misc.VM.initializeOSEnvironment();
// 将主线程添加到线程组中
Thread current = Thread.currentThread();
current.getThreadGroup().add(current);
// register shared secrets
setJavaLangAccess();
sun.misc.VM.booted();
}
设置虚拟机信息属性
thread.cpp->reset_vm_info_property(CHECK_0)
static void reset_vm_info_property(TRAPS) {
// the vm info string
ResourceMark rm(THREAD);
const char *vm_info = VM_Version::vm_info_string();
// java.lang.System class
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
instanceKlassHandle klass (THREAD, k);
// setProperty arguments
Handle key_str = java_lang_String::create_from_str("java.vm.info", CHECK);
Handle value_str = java_lang_String::create_from_str(vm_info, CHECK);
// return value
JavaValue r(T_OBJECT);
// 看这里,调用的是Java类System的 public static String setProperty(String key, String value); 方法,这个方法很简单,就不介绍了
JavaCalls::call_static(&r,
klass,
vmSymbols::setProperty_name(),
vmSymbols::string_string_string_signature(),
key_str,
value_str,
CHECK);
}
针对获取8个基础类型的值的方法进行优化,得到一个快速jni函数
thread.cpp->quicken_jni_functions()
这里函数里面用到的都是汇编代码,太复杂了,就不讲了,明白这里的含义就行,就是对基础类型的值的获取函数优化了,可以快速获取。
计算得到系统类加载器
thread.cpp->SystemDictionary::compute_java_system_loader(THREAD)
void SystemDictionary::compute_java_system_loader(TRAPS) {
KlassHandle system_klass(THREAD, WK_KLASS(ClassLoader_klass));
JavaValue result(T_OBJECT);
/* 看这一行,又调到Java的ClassLoader类的 getSystemClassLoader 方法了
template(getSystemClassLoader_name, "getSystemClassLoader")
*/
JavaCalls::call_static(&result,
KlassHandle(THREAD, WK_KLASS(ClassLoader_klass)),
vmSymbols::getSystemClassLoader_name(),
vmSymbols::void_classloader_signature(),
CHECK);
// 对应结果就是java 的 AppClassLoader 类
_java_system_loader = (oop)result.get_jobject();
CDS_ONLY(SystemDictionaryShared::initialize(CHECK);)
}
ClassLoader.getSystemClassLoader()
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl; // AppClassLoader 类
}
private static synchronized void initSystemClassLoader() {
if (!sclSet) {
if (scl != null)
throw new IllegalStateException("recursive invocation");
// 这里又涉及Launcher类
sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
Throwable oops = null;
// 此时的 scl 就是 AppClassLoader
scl = l.getClassLoader();
try {
scl = AccessController.doPrivileged(
new SystemClassLoaderAction(scl));
} catch (PrivilegedActionException pae) {
oops = pae.getCause();
if (oops instanceof InvocationTargetException) {
oops = oops.getCause();
}
}
if (oops != null) {
if (oops instanceof Error) {
throw (Error) oops;
} else {
// wrap the exception
throw new Error(oops);
}
}
}
sclSet = true;
}
}
***Launcher 类 ***
public Launcher() {
ExtClassLoader var1;
try {
var1 = Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException var10) {
throw new InternalError("Could not create extension class loader", var10);
}
try {
// 这一行,系统类加载器就是 AppClassLoader 类
this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
} catch (IOException var9) {
throw new InternalError("Could not create application class loader", var9);
}
// 并把该加载器设置到线程的上下文中
Thread.currentThread().setContextClassLoader(this.loader);
String var2 = System.getProperty("java.security.manager");
if (var2 != null) {
SecurityManager var3 = null;
if (!"".equals(var2) && !"default".equals(var2)) {
try {
var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
} catch (IllegalAccessException var5) {
} catch (InstantiationException var6) {
} catch (ClassNotFoundException var7) {
} catch (ClassCastException var8) {
}
} else {
var3 = new SecurityManager();
}
if (var3 == null) {
throw new InternalError("Could not create SecurityManager: " + var2);
}
System.setSecurityManager(var3);
}
}
原文地址:https://blog.csdn.net/zhang527294844/article/details/135850326
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!