IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java类加载机制深入理解及Arthas实战 -> 正文阅读

[Java知识库]Java类加载机制深入理解及Arthas实战

从一次Java类加载冲突说起

之前在网易做一个项目时,发现了如下java包是重复引入有冲突
在这里插入图片描述

分析

学会了用Arthas工具(Arthas 是Alibaba开源的Java诊断工具)分析加载的类sc -df org.apache.commons.codec.*,还有dependency.txt,目前看:

1.有直接引用的,用直接引用的

2.都是间接的,用最新的

dependency.txt中如下httpcore确实被两个引用到了


[[1;34mINFO[m] |  +- org.apache.httpcomponents:httpcore:jar:4.4.9:compile

[[1;34mINFO[m] |  \- commons-codec:commons-codec:jar:1.11:compile

[[1;34mINFO[m] +- commons-io:commons-io:jar:1.3.2:compile

[[1;34mINFO[m] +- com.netease.cloud:nos-sdk-java:jar:1.2.6:compile

[[1;34mINFO[m] |  +- org.apache.httpcomponents:httpcore:pom:4.1:compile


那么Java的类加载机制到底是怎么样的?

如上的例子,说明引入同名的jar包的情况是存在的,可能有人奇怪为什么会这样,这正是Java类加载机制需要回答的问题。如下图简单明了说明了类加载机制过程和优先级
在这里插入图片描述
我们可以用一段代码验证一下

// First, check if the class has already been loaded 先检查有没有加载过,加载过就不用在加载了,简单
Class c = findLoadedClass(name); 
if (c == null) {  --如果还没加载
        long t0 = System.nanoTime(); 
        try {                        
             if (parent != null) {                   c = parent.loadClass(name, false);                          } 
			 else {                             c = findBootstrapClassOrNull(name);                               } 
			 //如果不存在父类加载器,就检查是否是由启动类加载器加载的类,通过调用本地方法native Class findBootstrapClass(String name)                            
		} catch (ClassNotFoundException e) {
		    ...
        }               
        return c;

深入理解Java类加载机制

如果把JVM比喻成一个俱乐部,那么这个俱乐部的会员都是谁请来的呢?类似于传销模式那样

  • 首先,特点就是灵活。没有死板的规定,从一个文件中读取,而是多种途径,由应用自己决定。体现了“去中心化”的邀请

  • 新会员加入时,引荐的类都必须先转给父辈,父类来加载,加载不成功才由本类加载;父辈的老朋友,必须由父辈邀请,而且邀请前看看他是否已经在俱乐部了,这样的好处是

    • 确保不重复入会

    • 老朋友是父类的,不会加载不一样的

  • 这个机制是保证“增量优化”

  • 由不同ClassLoader对象加载的同名类属于不同类

JVM看来是个松散俱乐部,你引荐的和他引荐的可能是相同人或者同名人,不要紧,你的圈子里,只认由加载你的加载器加载的那个类

那么问题来了,为什么Tomcat不遵守这个规定?

双亲委派机制不是java的强制规范,但是是一种推荐标准

好处如下所说,一个强规则的等级社会,确保基础的类,比如java.lang.Object不会出现紊乱

那么tomcat为什么要故意绕开这种机制,因为具体情况不同:

  1. 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。 如果使用默认的类加载器机制,那么是无法加载两个相同类库的不同版本的,默认的累加器是不管你是什么版本的,只在乎你的全限定类名,并且只有一份

  2. 部署在同一个web容器中相同的类库相同的版本可以共享。

  3. web容器也有自己依赖的类库,不能于应用程序的类库混淆

  4. jsp热修改问题

我们想我们要怎么实现jsp文件的热修改(楼主起的名字),jsp 文件其实也就是class文件,那么如果修改了,但类名还是一样,类加载器会直接取方法区中已经存在的,修改后的jsp是不会重新加载的。那么怎么办呢?我们可以直接卸载掉这jsp文件的类加载器,所以你应该想到了,每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件。


Arthas实战分析

首先,Arthas非常好用(但是注意尽量避免用到生产环境,踩过坑,对生产环境性能和稳定性有影响,毕竟其原理是替换生产在运行的class)
使用过后分析,现在jvm中实际运行的类,不再是jar包中了,很多都是动态代理的
为什么?公共的功能统一加!!! 比如

  • 日志多打一些

  • 执行时间统计出来

  • 统一走某个session验证

实战中有很多例子,值得思考的是,就算动态代理更慢,但是哨兵和SpringBoot的都选了动态代理;而不选择快但是麻烦的静态代理(编译时就确定)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:09:53  更:2022-04-09 18:12:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:02:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码