类加载机制spi,类加载机制有哪些类加载器
终极管理员 知识笔记 113阅读
会将class文件这个二进制静态文件转化到方法区里面转化为方法区的时候会有一个结构的调整将静态的存储文件转化为运行时数据区这个转化等于说又回到了加载。

接着到了方法区的运行时数据区以后在java堆内存里面生成一个当前类的class对象作为方法区里面这个类被各种访问的一个入口。比如说object类它是所有类都继承它访问它所以它也需要一个被各种类访问的入口。object类先加载加载完成之后它经过这一系列的操作把自己java.lang.object放到这个堆里面要让其他的类进行访问这个也是加载。
第四步继续验证接着元数据验证它会对字节码描述的信息进行语义分析比如这个类是不是有父类是不是实现了父类的抽象方法是不是重写了父类的final方法是不是继承了被final修饰的类等等。

然后字节码验证通过数据流和控制流分析确定程序语义是合法的、符合逻辑的比如操作数栈的数据类型与指令代码序列是不是可以配合工作方法中的类型转换是不是有效等等。
最后符号引用验证确保解析动作可以正确执行比如说通过符号引用是不是可以找到对应的类和方法符号引用中类、属性、方法的访问性是不是能被当前类访问等验证完成之后需要做准备。
第五步分配内存空间准备就是给类的静态变量分配内存并赋予默认值。我们的类里可能会包含一些静态变量 比如说public static int a 12; 得给a这个变量分配个默认值 0再比如public static User user new User(); 给 static的变量User分配内存并赋默认值null。如果是final修饰的常量就不需要给默认值了直接赋值就可以了。
第六步解析解析就是将符号引用变为直接引用该阶段会把一些静态方法替换为指向数据储存在内存中的指针或者句柄也就是所谓的直接引用这个就是静态链接过程是在初始化之前完成。有静态链接就有动态链接动态链接是在程序运行期间完成将符号引用替换为直接引用比如静态方法里面有个方法在运行的时候方法是存放在常量池中的符号运行到这个符号就是找这个符号对应的方法区因为代码的指令是加载到方法区里面去的最后把方法对应代码的地址放到栈帧中的动态链接里。
编译器中的解析阶段其目的是将符号引用如变量、函数等名字转换成直接引用如指向内存中的地址从而使程序能够正确地执行。直接引用是指程序中直接使用的方法或数据在内存中对应的地址。在程序编译期间编译器将所有的方法和数据按照一定的规则映射到内存中的不同位置生成可执行文件。在程序运行期间程序通过直接引用来访问这些方法和数据直接引用一般是一个绝对地址或偏移量。因此在程序运行时操作系统需要将程序中的符号引用转换成直接引用以正确地访问方法和数据。符号引用是指程序中使用的方法或数据的标识符不是直接的内存地址。在编译期间编译器不能确定符号引用对应的具体地址因为这些方法和数据在运行时可能会被加载到不同的内存地址上。因此在编译期间编译器将符号引用记录在符号表中并在链接期间将符号引用解析为直接引用。在操作系统加载程序之前链接器会根据符号表中的信息找到并解析程序中所有的符号引用将它们转换为直接引用。静态链接是指将程序中所有需要用到的代码和数据在编译时就全部链接成一个可执行文件的过程。在静态链接过程中编译器会将静态库中的函数和变量复制到可执行文件中形成一个完整的可执行文件。在程序运行时所有的代码和数据都存在于内存中程序不需要再依赖外部库文件或动态链接库。静态链接的缺点是可执行文件较大不易于维护和更新。动态链接是一个程序运行时运行期间连接目标文件模块的过程将需要的代码添加到进程的地址空间中并将不同的模块组合在一起使它们能够相互调用。在动态链接的过程中程序中的符号引用被动态解析为直接引用这样程序才能正确地访问方法和数据。动态链接的好处是减小了程序的大小同时也方便了程序的更新和维护。常见的动态链接库DLL就是使用动态链接方式加载的。在静态链接过程中一些静态方法会被替换成直接引用这个过程在程序初始化之前完成。动态链接是在程序运行期间完成它会将符号引用替换成直接引用使程序能够正确地访问方法和数据。具体来说动态链接会将符号引用对应的方法的代码地址放到栈帧中的动态链接里从而实现符号引用到直接引用的转换。第七步初始化了初始化就是对类的静态变量初始化为指定的值并且会执行静态代码块。比如准备阶段的public static final int a 12;这个变量就是准备阶段给static变量a赋了默认值0这一步就该把12赋值给它了。还有static的User public static User user new User(); 把User进行实例化。
第八步就是使用和卸载了到此整个加载流程就走完了。
如果您需要转载或者搬运这篇文章的话非常欢迎您私信我哦~