微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

jvm---类加载器1

文章目录

1.jvm虚拟机内存模型

   类加载子系统
    运行时数据区:  堆
                  栈
                  本地方法方法区(元空间):常量+静态变量+类元信息
                  程序计数器
    字节码执行引擎

2.类加载过程

 加载; 在硬盘上查找并通过IO读入字节码文件,使用类时才会加载,例如调用类的main()方法,new对象等等
 验证: 校验字节码文件的正确性
 准备: 给类的静态变量分配内存,并赋予认值
 解析: 将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针,
      或句柄等(直接引用),这是所谓的静态连接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为
      直接引用
 初始化: 对类的静态变量初始化为指定的值,执行静态代码
public class Tuling {
   public static void main(String[] args) {
       System.out.println(String.class.getClassLoader());
       System.out.println(com.sun.crypto.provider.DESedeKeyFactory.class.getClassLoader().getClass().getName());
       System.out.println(Tuling.class.getClassLoader().getClass().getName());
       System.out.println(ClassLoader.getSystemClassLoader().getClass().getName());
   }

运行结果:
null
sun.misc.Launcher$ExtClassLoader

sun.misc.Launcher$AppClassLoader

sun.misc.Launcher$AppClassLoader

3.类加载器:

启动类加载器: jvm运行的位于jre/lib 目录下的核心类库 比如:rt.jar, charsets.jar等
扩展类加载器: 负责加载 位于jie的lib目录下的ext扩展目录中的jar类包
应用程序类加载器: 负责加载classpath路径下的类包,主要就是加载你自己写的那些类
自定义加载器:负责加载用户自定义路径下的类包

4. 查看jvm字节码执行情况

  • javap -c Tuling.class

5. 自定义类加载器 和类加载器不生效的处理

  • https://www.cnblogs.com/sunhao1234/p/12343967.html
    // 自定义类加载器
package com.tuling;

/**
 * Title: User
 * Description: Todo
 *
 * @author hfl
 * @version V1.0
 * @date 2020-11-23
 */
public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("关闭资源,user " + name + "即将回收");
    }

    public void sout(){
        System.out.println("=============自己的加载器加载类调用方法============");
    }

}

package com.tuling;

import java.io.FileInputStream;
import java.lang.reflect.Method;

/**
 * Title: MyClassLoaderTest
 * Description: Todo
 *
 * @author hfl
 * @version V1.0
 * @date 2020-11-23
 */
public class MyClassLoaderTest {
    static class MyClassLoader extends ClassLoader {
        private String classpath;

        public MyClassLoader(String classpath) {
            this.classpath = classpath;
        }

        private byte[] loadByte(String name) throws Exception {
            name = name.replaceAll("\\.", "/");
            FileInputStream fis = new FileInputStream(classpath + "/" + name + ".class");
            int len = fis.available();
            byte[] data = new byte[len];
            fis.read(data);
            fis.close();
            return data;
        }

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

            try {
                byte[] data = loadByte(name);
                return defineClass(name, data, 0, data.length);
            } catch (Exception e) {
                e.printstacktrace();
                throw new ClassNotFoundException();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        MyClassLoader classLoader = new MyClassLoader("D:/test");
        Class<?> clazz = classLoader.loadClass("com.tuling.User");
        Object obj = clazz.newInstance();
        Method method = clazz.getDeclaredMethod("sout", null);
        method.invoke(obj, null);
        System.out.println(clazz.getClassLoader().getClass().getName());
    }
}

运行结果:

=自己的加载器加载类调用方法
com.tuling.MyClassLoaderTest$MyClassLoader


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐