JVM系列产品手记文件目录
vm虚拟机的根本定义class文件构造class文件加载过程jvm运行内存实体模型JVM常见命令GC与调优
Class文件加载过程
JVM加载Class文件关键分3个过程:Loading 、Linking、Initialzing
1.Loading
Loading的过程便是根据类加载器将.class文件加载到jvm运行内存中过程。必须了解双亲委派体制、类加载器ClassLoader,加载过程如下所示。
ClassLoader
不一样的类加载器加载范畴不一样,以Java8中的为例子。
BootClassLoader 加载范畴
sun.boot.class.pahtExtClassLoader 加载范围java.ext.dirsAppClassLoader 加载范畴java.class.pathCustomClassLoader 可自定加载范畴
前三个加载器来源于JDK的Launcher类,三个ClassLoader做为Launcher的内部类,有兴趣可以检查下源代码。
开发人员还可以自定的ClassLoader,自定义记述范畴。
双亲委派体制
自底向上查验此类是不是已经加载,parent方位;自顶向下开展类的具体搜索和加载,child方位。 类的加载遵循双亲委派体制,主要是出自于安全性的考虑到。双亲委派体制是怎样完成的,下边源代码会表述。
留意:双亲委派中存有所说的父加载器并并不是加载器的加载器,仅仅翻泽的问题,别搞混了类的承继定义。
ClassLoader源代码
ClassLoader源码中较为主要的一个函数公式是loadClass(),实行过程是:findLoadedClass()->parrent.loadClass()->findClass(),第一步是自底向上查看是不是已经加载,第二步是自顶向下搜索加载类。这儿就要求或者说完成了双亲委派体制。详尽见ClassLoader的源代码。
自定ClassLoader
怎样自定ClassLoader?可以承继ClassLoader类,再次自身的findClass(),在里面启用defineClass()来建立自定加载特殊范畴的类。
怎样摆脱双亲委派体制,哪一种情况下摆脱过?
从以上的ClassLoader源代码中大约能看得出是怎样完成了双亲委派体制的,从这下手可以根据2种方法摆脱该体制:
super(parent)特定parent会摆脱该体制自定ClassLoader重新写过loadClass()还可以摆脱
什么时候摆脱过?双亲委派体制并非不可以摆脱,一些特别情景下也会挑选摆脱该体制。
JDK 1.2以前,自定ClassLoader务必重新写过loadClass(),摆脱过。进程ThreadContextClassLoader可以完成基本类启用完成类编码,根据
thread.setContextClassLoader特定。热启动热部署,如tomcat都是有自身控制模块特定的classloader,可以加载同一类库的不一样版本号。
Class实行方法
Class实行方法分成3种:表述实行、编译程序实行、混和实行,都各有优点和缺点,可根据主要参数特定。
- 1.表述实行:应用bytecode intepreter 编译器表述实行,该方式运行迅速,实行偏慢,可根据-Xint主要参数特定该方式。
- 2.编译程序实行:应用 Just in time Complier JITc语言编译器编译程序实行,该方式实行迅速,编译程序比较慢,可根据-Xcomp主要参数特定该方式。
- 3.混和实行:默认设置的方式,编译器 网络热点编码编译程序,逐渐表述实行,运行较快,对网络热点编码开展实时监测和编译成当地执行命令,可根据-Xmixed主要参数特定该方式。
网络热点编码检测:多次被启用的办法用方式计数,多次被启用的循环系统用循环计数,可根据主要参数-XX:CompileThreshold = 10000特定开启JIT编译程序的阀值。
2.Linking
Linking连接的过程分3个环节:Vertification、Preparation、Resolution。
- Vertification: 认证Class文件是不是合乎JVM要求。
- Preparation:给静态数据成员变量赋初始值
- Resolution:将类、方式、特性等标记引入表述为直接引用;常量池中的倒三角符号引入表述为表针、偏移等内存地址的直接引用
3. Initializing
启用复位编码clint,给静态数据成员变量赋默认值。
这儿可以掌握下务必复位的5种状况:
new getstatic putstatic invokestatic命令,浏览final自变量以外java.lang.reflect对类开展反射面启用时复位派生类的情况下,成员变量务必复位vm虚拟机运作时,强制执行的主类务必复位动态语言适用
java.lang.invoke.MethodHandler表述的效果为REF_getstatic REF_putstatic REF_invokestatic的方式句柄时,此类务必复位。
4.汇总思索
程序设计模式中单例设计模式的多重查验的完成,INSTANCE是不是必须加valatile?
public class Mgr06 {
// 是不是必须加volatile?
private static volatile Mgr06 INSTANCE;
private Mgr06() {
}
public static Mgr06 getInstance() {
if (INSTANCE == null) {
//双向查验
synchronized (Mgr06.class) {
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// new 了目标,不以null,但没完成自变量的复位拷贝,目标处在半复位状 态,其他进程有可能得到半复位的目标。
INSTANCE = new Mgr06();
}
}
}
return INSTANCE;
}
}
复制代码
本人觉得是必须加的。思索方位, class文件load到运行内存,给静态变量赋默认值,再赋初始值,new 对象的情况下,最先要申请办理内存空间,随后给成员变量赋默认值,下面给成员变量赋初始值,这一环节中对象有可能处在半复位情况,多线程高并发下其他线程有可能得到半复位的对象,加volatile可确保线程的看得见性。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。