JVM类加载器及其详解

news2024/11/26 16:25:39

1.JVM加载过程分析

1.1加载流程图

在这里插入图片描述

1.2双亲委派机制

  • 引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等
  • 扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包
  • 应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类
  • 自定义加载器:负责加载用户自定义路径下的类包
    在这里插入图片描述
    这里类加载其实就有一个双亲委派机制,加载某个类时会先委托父加载器寻找目标类,找不到再委托上层父加载器加载,如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载路径中查找并载入目标类。
    比如我们的Math类,最先会找应用程序类加载器加载,应用程序类加载器会先委托扩展类加载器加载,扩展类加载器再委托引导类加载器,顶层引导类加载器在自己的类加载路径里找了半天没找到Math类,则向下退回加载Math类的请求,扩展类加载器收到回复就自己加载,在自己的类加载路径里找了半天也没找到Math类,又向下退回Math类的加载请求给应用程序类加载器,应用程序类加载器于是在自己的类加载路径里找Math类,结果找到了就自己加载了。。

1.为什么要设计双亲委派机制?

  • 沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
  • 避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性
package java.lang;

public class String {
    public static void main(String[] args) {
        System.out.println("*******my String class*****");
    }
}

在这里插入图片描述
在这里插入图片描述
说明:在引导类加载这个路径这个方法的时候,已经找到这个这个,会直接调取引导类加载器的方法,不会加载自己定义的方法。

2.双亲委派机制示例

package com.tuling.jvm;

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

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;
        }

        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.jvm.User1");
        Object obj = clazz.newInstance();
        Method method = clazz.getDeclaredMethod("sout", null);
        method.invoke(obj, null);
        System.out.println(clazz.getClassLoader().getClass().getName());
    }
}

1.当在程序中有user1这个实体类的时候
在这里插入图片描述
运行结果
在这里插入图片描述
2.当在程序中有user1这个实体类的时候
在这里插入图片描述
运行结果
在这里插入图片描述

3.打破双亲委派机制

package com.tuling.jvm;

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

public class MyClassLoaderTest2 {
    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;
        }

        protected Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                       long t0 = System.nanoTime();
                        long t1 = System.nanoTime();

                        if(!name.startsWith("com.tuling.jvm")){
                            c=this.getParent().loadClass(name);
                        }else{
                            c = findClass(name);
                        }

                        // this is the defining class loader; record the stats
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                  }

                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }


        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.jvm.User1");
        Object obj = clazz.newInstance();
        Method method = clazz.getDeclaredMethod("sout", null);
        method.invoke(obj, null);
        System.out.println(clazz.getClassLoader().getClass().getName());
    }
}

1.相关文件截图
在这里插入图片描述
2.运行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/595788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python倒序的实现方法介绍

Python倒序的实现方法介绍 Python是一种高级编程语言&#xff0c;被广泛用于数据处理、人工智能、Web开发等领域。其中&#xff0c;倒序是常见的一种操作需求。Python提供了多种实现倒序的方法&#xff0c;下面进行详细介绍。 1. 切片 切片是Python中常用的语法&#xff0c;…

chatgpt赋能python:Python倒序循环–优化你的编程效率

Python倒序循环 – 优化你的编程效率 在Python编程中&#xff0c;倒序循环是一种非常强大的操作。它可以用于遍历一个序列并对其中的元素进行逆序处理&#xff0c;从而提高编程效率。本文将介绍Python倒序循环的优势及如何在编程中使用。 什么是Python倒序循环 在传统循环中…

Web应用技术(第十五周/END)

本次练习基于how2j和课本&#xff0c;进行SSM的初步整合&#xff0c;理解SSM整合的原理、好处。 SSM整合应用 1.简单的实例项目&#xff1a;2.原理分析&#xff1a;3.浅谈使用SSM框架化&#xff1a; 1.简单的实例项目&#xff1a; how2j 2.原理分析&#xff1a; 具体见流程图…

MySQL-1-基础

MySQL 简介 mysql-server #提供服务 mysql-client #提供SQL命令 官网地址&#xff1a;https://dev.mysql.com/downloads/ https://downloads.mysql.com/archives/community/查看帮助文档 mysql> ? contents一、安装MySQL 1.1、二进制安装mysql5.7-linux 安装前准备 sh…

SpringBoot 的创建和使用

Spring Boot 的优点 Spring的出现是为了简化 Java 程序开发,而 SpringBoot 的出现是为了简化 Spring 程序开发. SpringBoot 就是 Spring脚手架 快速集成框架&#xff0c;Spring Boot提供了启动添加依赖的功能&#xff0c;用于秒级集成各种框架。内置运行容器&#xff0c;无需配…

python+vue大学新生入学报道交流平台pycharm

本系统的用户可分学生、教师、管理员三类。 管理员模块 1)登录&#xff1a;管理员输入用户名、密码&#xff1b;选择“管理员”角色&#xff1b;点击登录按钮。 2)管理员主界面&#xff1a;以管理员身份登录成功后&#xff0c;选择进入网站系统管理模块&#xff1b;选择进入首页…

Python字符串类型的使用

文章目录 Python中的字符串类型一、字符串的常用操作二、字符串的常用函数 Python中的字符串类型 注意&#xff1a;字符串为不可修改类型 python中没有单独的字符类型&#xff0c;字符就是长度为1的字符串。 通常创建字符串的方式&#xff1a;一般用单引号&#xff08;’ &am…

从数据库到固态硬盘的读取过程

应用程序到数据库到操作系统到固态硬盘 在我研究了从应用程序发送的简单 SQL 查询是如何最终存储到磁盘的过程中&#xff0c;我发现术语 “页&#xff08;page&#xff09;” 和 “块&#xff08;block&#xff09;” 可能是软件工程中最多用的概念之一。有数据库页&#xff08…

Python新技术和趋势:如何应对Python生态的变化和发展趋势

第一章&#xff1a;引言 Python作为一门简洁、优雅且易于学习的编程语言&#xff0c;一直以来都备受开发者的喜爱。它拥有强大的生态系统和活跃的社区&#xff0c;使得Python在各个领域都有广泛的应用。然而&#xff0c;随着时间的推移&#xff0c;Python生态系统也在不断演变…

STM32H743烧录后无法识别Jlink的问题

利用Cubemx生成H743的代码&#xff0c;点击烧录后&#xff0c;无法再识别到Jlink了&#xff0c;只能烧录时按着复位再松开&#xff08;类似51单片机&#xff09;。 烧录后不运行&#xff0c;用keil进行debug&#xff0c;调试发下芯片进去内存管理错误中断。 经过不断调试发现&…

vuex核心

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是状态管理&#xff1f;二、复杂的状态管理1.随着代码越来越多&#xff0c;需要管理的状态越来越复杂&#xff0c;当多个组件共享状态时&#xff0c;单…

​刷爆朋友圈!前百度总裁陆奇最新AI重磅演讲:我的大模型世界观​

陆奇的演讲刷屏了&#xff0c;我认真看了他的演讲稿&#xff0c;收获颇丰。 陆奇提到&#xff0c;人类社会的发展&#xff0c;大致可分为&#xff1a;农业化、工业化和数字化三个阶段。 在三个递进的阶段中&#xff0c;人类一直在探索如何减少烦琐且消耗能量的体力和脑力劳动&a…

安装 MySQL 8 如何在生产环境中

文章结构 安装生产环境安装 MySQLDocker 安装 MySQL 相关资源网址 安装 生产环境安装 MySQL 一般的&#xff0c;我们使用 RPM 包的方式完成 MySQL 的安装&#xff0c;本教程参考了官方的安装说明&#xff0c;安装的具体步骤如下&#xff1a; 什么是 RPM&#xff1a; rpm&…

chatgpt赋能python:Python代码怎么读?

Python代码怎么读&#xff1f; Python是一种高级编程语言&#xff0c;它具有明确简洁的语法和丰富的资源库。它是一个简单易学的语言&#xff0c;非常适合编写快速原型。 但是&#xff0c;对于初学者来说&#xff0c;Python代码可能看起来有点吓人。好消息是&#xff0c;Pyth…

前端基础(HTML)——html介绍 常用标签 几个案例

引出 html是啥&#xff0c;常见的标签&#xff0c;几个例子 一、概述 1.1 HTML是什么&#xff1f; Hyper Text Markup Language (超文本标记语言) 简写:HTML&#xff0c;HTML 通过标签来标记要显示的网页中的各个部分。网页文件本身是一种文本文件&#xff0c; 通过在文本文…

solr快速上手:创建核心/索引/core(四)

0. 引言 上节&#xff0c;我们讲解了solr的核心配置文件managed-schema&#xff0c;了解定义索引的核心配置标签&#xff0c;今天我们来实操配置&#xff0c;创建一个索引 solr快速上手&#xff1a;solr简介及安装&#xff08;一&#xff09; solr快速上手&#xff1a;核心概…

chatgpt赋能python:Python修改上一行:简化你的工作流程

Python修改上一行&#xff1a;简化你的工作流程 作为一名有10年Python编程经验的工程师&#xff0c;我一直在探索更加高效的工作方式。今天&#xff0c;我想向大家分享的是Python修改上一行的技巧&#xff0c;让你的工作流程更加简化&#xff0c;提高工作效率。 什么是Python…

【利用AI让知识体系化】进程和线程

文章目录 1. 介绍1.1 什么是进程1.2 什么是线程1.3 进程和线程之间的关系 2. 进程的概念2.1 进程的定义2.2 进程的特征2.3 进程的状态2.4 进程的调度 3. 线程的概念3.1 线程的定义3.2 线程的优点3.3 线程的实现3.4 线程的调度 4. 进程和线程的比较4.1 进程和线程的区别4.2 进程…

chatgpt赋能python:Python修改Word二级标题的SEO优化

Python修改Word二级标题的SEO优化 Python是一种非常流行的编程语言&#xff0c;可以用于许多各种各样的应用程序。其中之一是用Python处理文档&#xff0c;其中一个重要的任务是修改文档中的标题。二级标题是英文文档中非常常见的元素&#xff0c;这篇文章将介绍如何使用Pytho…

【MySQL新手到通关】第七章 聚合函数

文章目录 0. 前置1. 聚合函数介绍1.1 AVG 和 SUM 函数1.2 MIN 和 MAX 函数1.3 COUNT函数 2. GROUP BY2.1 基本使用 3. HAVING3.1 基本使用3.2 WHERE和HAVING的对比 0. 前置 为了方便测试&#xff0c;我们导入一些数据 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ------…