Java Class卸载与ClassLoader

如何在Jetson Nano上快速搭建Pytorch环境(含torchvision安装教程) 本文详细介绍了在Jetson Nano上快速搭建PyTorch环境的完整步骤,包括系统准备、PyTorch安装优化、torchvision编译安装及环境测试。通过本指南,开发者可以高效部署深度学习开发环境,充分利用Jetson Nano的GPU加速能力进行计算机视觉项目开发。 阅读详情
JVM中的Class只有满足以下三个条件,才能被GC回收,也就是该Class被卸载(unload):

   - 该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。
   - 加载该类的ClassLoader已经被GC。
   - 该类的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法

 
jsp和java类是完全不一样的概念。
jsp->servlet 在web容器中,你的servlet是单例的,也是无状态的, 线程安全的。也就是只有一个对象,
jsp改变以后,web容器只要把相应的servlet对象更新就好了。

而java呢?
可能这个类在你的应用中有n个实例,与这些实例单向,双向关联的又有n个实例。如果你修改了,这些jvm存在的老的实例对象怎么办????
java这类静态语言无法实现象asp,php,jsp的效果的。


 weblogic热部署原理

Weblogic允许在wls运行时部署组件的新版本。这个过程被称作热部署。因为java classloader没有任何一种机制来卸下一系列存在的类,也不能用类的新版本来替换老版本,为了在一个运行的虚拟机中更新相关的类,classloader必须被替换掉。当它被替换时,它所装载的所有类以及衍生的子classloader也要被重新装载。这些类的所有实例也必需被重新装载。在wls中,每一个应用组件都有一个层次化的classloaders,它们都是system classloader的子类,这种结构有助于每个应用或应用的一部分能被单独重新加载,而不会影响其它的组件。

 

类加载器的种类:
  1. Bootstrap ClassLoader/启动类加载器 
    主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
  2. Extension ClassLoader/扩展类加载器 
    主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
  3. System ClassLoader/系统类加载器 
    主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
  4. User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) 
    在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
类加载器的特性:

 

  1. 每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。
  2. 为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构。

 

 

自定义类加载器加载一个类的步骤
classloader-load-class
classloader-load-class
 
ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:
// 检查类是否已被装载过        
Class c = findLoadedClass(name);        
if (c == null ) {        
         // 指定类未被装载过        
         try {        
                 if (parent != null ) {        
                         // 如果父类加载器不为空, 则委派给父类加载        
                         c = parent.loadClass(name, false );        
                 } else {        
                         // 如果父类加载器为空, 则委派给启动类加载加载        
                         c = findBootstrapClass0(name);        
                 }        
         } catch (ClassNotFoundException e) {        
                 // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其        
                 // 捕获, 并通过findClass方法, 由自身加载        
                 c = findClass(name);        
         }        
}

 

 

线程上下文类加载器
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。
// Now create the class loader to use to launch the application        
try {        
        loader = AppClassLoader.getAppClassLoader(extcl);        
catch (IOException e) {        
        throw new InternalError(        
"Could not create application class loader" );        
}         
     
// Also set the context class loader for the primordial thread.        
Thread.currentThread().setContextClassLoader(loader);    
 
以上代码摘自sun.misc.Launch的无参构造函数Launch()。
使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).
线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.
使java类加载体系显得更灵活.
随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。
当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,
防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。

 

三.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
 
例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*LoaderSample2.java*/

import    java.net. * ; 
import    java.lang.reflect. * ; 
public     class    LoaderSample2 { 
         public     static     void    main(String[] args) { 
                 try    { 
                        String path    =    System.getProperty( " user.dir " ); 
                        URL[] us    =    { new    URL( 
" file:// "     +    path    +     " /sub/ " )}; 
                        ClassLoader loader    =     new    URLClassLoader(us); 
                        Class c    =    loader.loadClass( " LoaderSample3 " ); 
                        Object o    =    c.newInstance(); 
                        Field f    =    c.getField( " age " ); 
                         int    age    =    f.getInt(o); 
                        System.out.println( " age is    "     +    age); 
                }    catch    (Exception e) { 
                        e.printStackTrace(); 
                } 
        } 
}

/*sub/Loadersample3.java*/

public     class    LoaderSample3 { 
         static    { 
                System.out.println( " LoaderSample3 loaded " ); 
        } 
         public     int    age    =     30 ; 
}
编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。

 

说明:如果LoaderSample3在classpath下能够找到,则由URLClassLoader的parent loader AppClassLoader来加载,如果不在classpath下

则由 URLClassLoader自己加载,即 LoaderSample3.getClass().getClassLoader() 是 URLClassLoader

运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。  
 
总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。
 
二.    扩展ClassLoader方法

我们目的是从本地文件系统使用我们实现的类装载器装载一个类。为了创建自己的类装载器我们应该扩展ClassLoader类,这是一个抽象类。我们创建一个FileClassLoader extends ClassLoader。我们需要覆盖ClassLoader中的findClass(String name)方法,这个方法通过类的名字而得到一个Class对象。
         public    Class findClass(String name) 
        { 
                 byte [] data    =    loadClassData(name); 
                 return    defineClass(name, data,    0 , data.length); 
        }

我们还应该提供一个方法loadClassData(String name),通过类的名称返回class文件的字 
节数组。然后使用ClassLoader提供的defineClass()方法我们就可以返回Class对象了。

public     byte [] loadClassData(String name) 
        { 
                FileInputStream fis    =     null ; 
                 byte [] data    =     null ; 
                 try    
                { 
                        fis    =     new    FileInputStream( new    File(drive    +    name    +    fileType)); 
                        ByteArrayOutputStream baos    =     new    ByteArrayOutputStream(); 
                         int    ch    =     0 ; 
                         while    ((ch    =    fis.read())    !=     - 1 ) 
                        { 
                                baos.write(ch); 
                                
                        } 
                        data    =    baos.toByteArray(); 
                }    catch    (IOException e) 
                { 
                        e.printStackTrace(); 
                } 
                 
                 return    data; 
        }

 

自定义ClassLoader实现java 热替换:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/

从模拟到实战:移远EC800M单片机MQTT接入OneNet全流程解析 本文详细解析了移远EC800M单片机通过MQTT协议接入OneNet平台的全流程,涵盖环境准备、模拟设备搭建、硬件迁移、数据交互调试及性能优化等关键步骤。针对常见问题如AT指令缓冲区溢出、心跳间隔设置等提供实战解决方案,帮助开发者高效实现物联网设备稳定接入。 阅读详情

相关推荐

FCKeditor 2.6.4 php版本任意文件上传——漏洞复现

一、漏洞描述 FCKeditor是目前最优秀的可见即可得网页编辑器之一,它采用JavaScript编写。具备功能强大、配置容易、跨浏览器、支持多种编程语言、开源等特点。它非常流行,互联网上很容易找到相关技术文档,国内许多Web项目和大型网站均采用了FCKeditor。 Fckeditor 低于 2.6.4 php 版本任意文件上传漏洞,当您的PHP环境配置为 GPC = Off 时可绕过currentfolder参数过滤上传脚本木马控制网站服务器 二、漏洞原理 漏洞版本:<=2.6.4 三、环境搭建

W小哥 1万+

java 卸载class_java加载卸载

双亲委派机制加载ClassLoader中定义了加载方法:protected Class> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has alrea...

weixin_39838028的博客 917

快速生成2D卡通人物的AI工具:开启Live2D角色创作的新时代

随着这一创新工具的推出,我们正见证着Live2D角色创作进入了一个全新的阶段。它不仅极大地简化了角色设计的过程,也为广大创作者提供了一种全新的表达方式。对于那些渴望将脑海中的构思迅速转化为现实的人来说,这无疑是一大福音。现在就访问项目主页,开始探索无限可能吧!t=O83A项目主页https://human3daigc.github.io/Textoon_webpage/

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 4764

51 java.lang.Class/java.lang.ClassLoader/InstanceKlass/ClassloaderData 的卸载

之前 碰到了一个 flink 基于 ChildFirstClassLoader 来进行任务隔离 导致的内存泄漏的问题然后 使用 demo 复现了一下 问题之后 想探索一下 java language 中 型的卸载相关并且会 拓展一些其他的知识以下测试用例基于 jdk8, 部分截图基于 jdk9。

970655147的专栏 949

Java利用ClassLoader实现的热加载和卸载

最近做项目的时候遇到这个问题,就是在服务器不重启的情况下实现版本替换,即项目中一部分的需要实时替换,甚至,对利用动态编译去生成很多临时; 那就需要解决两个问题: 1.如何实现的动态替换 2.如何实现卸载 当然,关于的动态编译,我会在今后的文章中写出; 一、实现的动态替换: 首先,同名同包的,在静态编译的时候是肯定无法通过的,在运行时也一定不行;这是为什么呢? 因为,所有的,...

bobozai86的博客 5709

JAVA加载卸载

JAVA加载卸载

YmovomY的博客 711

从代码热替换谈谈加载机制

知识点 谈谈Tomcat的代码热替换模块的热部署 各自使用场景 实现原理 谈谈OSGI的模块化热部署 了解加载机制双亲委派机制 概念 加载器 如何破坏双亲委派机制 其他应用场景 目标 我希望: (1)学习到代码热替换/模块热部署的实现原理 (2)了解Java加载机制、双亲委派机制 (3)破坏双亲委派机制的场景 (4)初步了解OSGI 正文 玩过Tomcat的朋友都应该了...

伊甸园 601

java 卸载class_Java Class卸载ClassLoader

JVM中的Class只有满足以下三个条件,才能被GC回收,也就是该Class卸载(unload):- 该所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。- 加载该ClassLoader已经被GC。- 该Java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该的方法jsp和java是完全不一样的概念。jsp->servlet ...

weixin_33278498的博客 2334

java 卸载class_Java --ClassLoader创建、加载class卸载class

一、java提供了三种ClassLoaderClass进行加载:1.BootStrap ClassLoader:称为启动加载器,是Java加载层次中最顶层的加载器,负责加载JDK中的核心库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该加载器从哪些地方加载了相关的jar或class文件:URL[] urls =sun.misc.Launc...

weixin_31049801的博客 1076

Java Class卸载ClassLoader ,class热替换

JVM中的Class只有满足以下三个条件,才能被GC回收,也就是该Class卸载(unload):    - 该所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。   - 加载该ClassLoader已经被GC。   - 该java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该的方法   jsp和java是完全不一样的概...

soledede 1074

Java --ClassLoader创建、加载class卸载class

一、java提供了三种ClassLoaderClass进行加载: 1.BootStrap ClassLoader:称为启动加载器,是Java加载层次中最顶层的加载器,负责加载JDK中的核心库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该加载器从哪些地方加载了相关的jar或class文件: URL[] urls = sun.mis...

weixin_30768661的博客 390

Java中的加载卸载

加载 Java中的代码都写在里面,源代码(.java文件)经过编译后会变成字节码(.class文件),当Java应用程序运行时,JVM会加载要用到的。 负责加载的是java.lang.ClassLoader的对象,ClassLoader的对象会根据的binary name(不知道怎么翻译,二进制名?)来读取的字节码,然后把这些字节码加载到JVM的方法区里,同时会在heap里面创建一个C...

面向学姐编程 3675

jvm卸载class条件的理解

需要满足以下3个条件才能算是“无用的”    1. 该所有的实例已经被回收  2. 加载该ClassLoder已经被回收  3. 该对应的java.lang.Class对象没有任何对方被引用   第2个条件有一些费解。 可能是因为ClassLoder保存了加载到jvm方法区的位置信息,保存了的引用。但是ClassLoader又不具备主动卸载

guohnu的博客 4105

class mywnd : pubic qwidget是什么意思_学了这么久java反射,你知道class.forName和classloader的区别吗?...

前两天头条有朋友留言说使用class.forName找不到,可以使用classloader加载。趁此机会总结一下,正好看到面试中还经常问到。一、加载机制上面两种加载的方式说到底还是为了加载一个java,因此需要先对加载的过程进行一个简单的了解。我们写好的程序,然后run运行,过程可以直接看下面这张图:往细了看大致分为5个阶段:(1)加载:java运行时候会生成一个class字...

weixin_39996496的博客 152

ClassLoader卸载Class一定被回收吗?Metaspace卸载真相曝光

揭秘Metaspace的Class卸载条件,厘清ClassLoader回收关系。只有当ClassLoader回收且满足JVM卸载条件时,Metaspace中的才可能被卸载,并非必然。深入解析触发机制GC行为差异,助你优化内存管理,避免元空间泄漏。值得收藏

QuickProceed的博客 438

jvm:卸载

jvm

amadeus_liu2的博客 562

classLoader加载的class回收

什么情况下,方法区中的才会被回收? 关于第二句的理解,加载该加载器ClassLoader已经被回收了,不单单是当前创建的ClassLoader回收了,而是要真正加载这个classClassLoader回收了(即保存当前class的ProtectionDomain被回收了),当前才会回收;这个和双亲委派机制有关!demo如下 输出的日志如下: 由以上可以分析出,mClassLoader虽然被回收了,但是看的出来ClassLoaderBean并没有回收,原因是ClassLoade

Android&前端 1700

使用 URLClassLoader 加载和卸载

使用 URLClassLoader 加载或卸载

Engure 1246

JAVA卸载重新安装

找到之前配置Java环境变量的配置然后删掉,CLASSPATH、JAVA_HOME、PATH中的环境都删除掉,一般删除Java后,PATH中的环境会被删掉。使用电脑管家把无用的注册表清除掉,如果要进入注册表删除,用win+R输入regedit,进入注册表。安装完jdk后,我们需要在命令执行框中安装一些jre,打开cmd,找到安装jdk的文件夹后输入。然后下载完后,就是普通的安装,要安装地址的话,要记一下地址,配置环境变量在使用。到Java安装途径下把Java文件夹删除干净,然后删除Java的缓存文件。

梁小布的博客 2万+

java 卸载class_卸载Java中的

小编典典可以卸载的唯一方法是,如果使用的加载器是垃圾回收。这意味着对每个单个的引用以及对加载器的引用都需要遵循dodo的方式。一种可能的解决方案是为每个jar文件提供一个Classloader,为每个AppServer提供一个Classloader,以将的实际加载委托给特定的Jar加载器。这样,您可以为每个App服务器指向jar文件的不同版本。不过,这并非微不足道。OSGi平台努力做到...

weixin_42524945的博客 1559

Java加载卸载

http://blog.csdn.net/feiyu8607/article/details/8308314 Java Class卸载ClassLoader: Java2012-12-17 17:02 2047人阅读 评论(0) 收藏 举报 JVM中的Class只有满足以下三个条件,才能被GC回收,也就是该Class卸载(unload):   

xiangbq的博客 1万+

Class热替换卸载

概述 名词解释:所谓热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。本文主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class卸载的原理。 Class热替换 ClassLoader中重要方法: loadClassClassLoader.loadClass(…) 是ClassLoader的入口点。当一个没有指明用

大鹏知识库 1930

蓝牙NRF51822芯片参考设计AD版原理图+PCB(4层板)+智能手环设计方案.zip

蓝牙NRF51822芯片参考设计AD版原理图+PCB(4层板)+智能手环设计方案,蓝牙模块采用4层板设计,板子大小为33x17mm,双面布局布线,蓝牙主控芯片NRF51822,主要器件包括SBQ24040,TPS3898A TPS62260等,AltiumDesigner 设计的工程文件,包括完整的原理图及PCB文件,可以用Altium(AD)软件打开或修改,可作为你产品设计的参考。

医院三网整体设计及下一代云数据中心网络安防加强.docx

医院三网整体设计及下一代云数据中心网络安防加强.docx

上一篇: java 通过Axis调用Webservice
下一篇: Spring Bean Scope Singleton Prototype 相互引用说明
feiyu8607
博客等级 码龄18年 26粉丝 51原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值