JVM总括四-类加载过程、双亲委派模型、对象实例化过程

JVM总括四-类加载过程、双亲委派模型、对象实例化过程

目录:JVM总括:目录

一、 类加载过程

类加载过程就是将.class文件转化为Class对象, 类实例化 的过程 ,(User user = new User(); 这个过程是 对象实例化 的过程);

一个.class文件只有一个Class对象(字节码对象),可以有无数个对象(例如:new User(););

1、Load:

将编译后的.class文件以二进制流的方式加载到JVM内存中,并转化为特定的数据结构,用到的就是 classLoad 二类加载器。这个过程中校验 cafe babe魔法数 、 常量池 、 文件长度 、 是否有父类 等。

2、Link:

分为验证、准备、解析三步。

验证:更为详细的验证,比如: final是否规范 (二次赋值不规范)、 static是否合理 (静态方法必须引用静态变量)、 类型是否正确 。

准备: 静态变量分配内存并设定默认值 (静态变量不赋值是有个默认值得),这个过程没有对象实例化。

解析:把类中的符号引用转化为 直接引用 ,完成内存结构布局。(符号引用转化为直接引用:例如:test1() { test2(); },这里test1调用test2方法就是符号引用,但实际test2()通过一个指针指向test2方法的内存地址,这个指针负责调用,它就是直接引用)。

3、Init:

执行类构造器, 执行静态代码块 , 为静态变量赋予正确的初始值 , 递归初始化父类 , 不 执行构造函数 。(先执行静态代码块,再执行静态变量)。

任何小写的class定义的类都有一个魔法属性:class,

int j;Class integerClass = int.class;Class integerClass1 =Integer.class;

二、类加载的原则:双亲委派模型

类加载是怎么确定类文件的位置呢?

1、Bootstrap:最高级的类加载器,装置最核心的类,如:Object、System、String;

2、Extension ClassLoader:JDK9之前的类加载器,以后的为 Platform ClassLoader ,加载系统的扩展类;

3、Application ClassLoader:应用类加载器,主要加载用户自定义CLASSPATH路径下的类。

类加载器 并非继承关系 ,只是以组合的方式服用父加载器功能,符合优先原则。

其中第二、第三层为java实现,用户可以自定义类加载器,第三层为C++实现,所有为null:


获取Bootstrap加载的类库:


Bootstrap加载的路径可以追加,在JVM增加启动参数,不过不建议修改:

Xbootclasspath/D:/test/src

自定义类加载器的情况:

1、隔离加载类:框架中吧类加载到不同的环境中

2、修改类加载方式:除了Bootstrap,其他类并非一定要加入。

3、扩展加载源:比如加载数据库;

4、防止源码泄露:可以对类进行加密,那加载的时候需要自定义加载器对类进行解密加载。

自定义ClassLoder,继承ClassLoader,重写findClass(),调用defineClass():

public class UserClassLoader extends ClassLoader {

    private String classpath;

    public UserClassLoader(String classpath) {

        this.classpath = classpath;

    }

    @Override

    protected Class<?> findClass(String name) throws ClassNotFoundException {

        try {

            byte [] classDate=getDate(name);

            if(classDate==null){

                throw new FileNotFoundException();

            }

            else{

                //defineClass方法将字节码转化为类

                return defineClass(name,classDate,0,classDate.length);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

        return super.findClass(name);

    }

    //返回类的字节码

    private byte[] getDate(String className) throws IOException{

        InputStream in = null;

        ByteArrayOutputStream out = null;

        String path=classpath + File.separatorChar +className.replace('.',File.separatorChar)+".class";

        try {

            in=new FileInputStream(path);

            out=new ByteArrayOutputStream();

            byte[] buffer=new byte[2048];

            int len=0;

            while((len=in.read(buffer))!=-1){

                out.write(buffer,0,len);

            }

            return out.toByteArray();

        }

        catch (FileNotFoundException e) {

            e.printStackTrace();

        }

        finally{

            in.close();

            out.close();

        }

        return null;

    }

}

UserClassLoader

调用,其中D:\\wp目录下为.class文件,里面有个Son.class

//自定义类加载器的加载路径

UserClassLoader myClassLoader=new UserClassLoader("D:\\wp");

//包名+类名

Class sonClass=myClassLoader.loadClass("com.Son");

if(sonClass!=null){

    Object obj=sonClass.newInstance();

    System.out.println(sonClass.getClassLoader().toString());

}


三、对象实例化

从字节码、执行步骤两个方面分析

1、字节码方面:

Objectobject=newObject();,通过javap -verbose -p查看对象创建的字节码指令:

(1)new:如果找不到Class对象就进行类加载,然后分配内存(本类路径上所有的属性都分配),其中对象的引用也是个变量也占内存(4个字节),这个指令执行完毕会把对象的压入虚拟机栈顶。

(2)dup:在栈顶复杂引用,如果<init>有参数,把参数压入操作栈,两个引用,压入栈底的用来赋值或保存到局部变量表中,栈顶引用作为句柄调用相关方法。

(3)invokespecial:调用对象实例化方法,通过栈顶方法调用<init>方法(也就是调用构造方法)。

2、执行步骤

(1)确认类元信息是否存在:接到new指令时,在metaspace检查类元信息是否存在,没有就在双亲委派模式下进行类加载,生成Class对象。

(2)分配对象内存:首先计算对象占用空间大小(成员变量是引用变量就分配4个字节大小的变量空间),在堆中划分内存空间给新对象(分配空间需要进行同步操作,如:cas)。

(3)设定默认值:成员变量设置不同形式的0值;

(4)设置对象头:设置对象的哈希码、锁信息、对象所属的类元信息,设置取决于JVM。

(5)执行init方法:初始化成员变量,执行代码块,调用类的构造方法,把堆对象首地址赋值给引用变量。

四、思考:ClassLoader.loadClasshe和Class.forName区别

1//12Class sonClass = Son.class;3//24Class aClass = Maint.class.getClassLoader().loadClass("com.Son");5//36Class bClass =Class.forName("com.Son");

代码2:

        其实这种方法调运的是:ClassLoader.loadClass(name, false)方法参数一:name,需要加载的类 的名称

参数二:false,这个类加载以后是否需要去连接

(不需要linking)

代码:3: 

其实这种方法调运的是:Class.forName(className, true, ClassLoader.getCallerClassLoader())方法 

参数一:className,需要加载的类的名称。 

参数二:true,是否对class进行初始化(需要initialize) 

参数三:classLoader,对应的类加载器

其中1、2都是将.class文件加载到JVM中,得到Class对象,但是 还没有连接(Link) , 静态代码块不会执行; 

代码3得到Class对象并且 已经完成初始化<clinit> ,静态代码块会执行。( Class.forName("com.mysql.jdbc.Driver");//通过这种方式将驱动注册到驱动管理器上)。

1、2、3都 不会执行对象的构造函数 。

五、思考:<clinit>和<init>区别

<clinit>是类(Class)初始化执行的方法,<init>是对象初始化执行的方法(构造函数);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容