【转】JVM类装载机制的解析,热更新的探讨(二)
同样,一个Class对象必须知道自己的超类、超级接口。因此,Class对象会引用自己的超类和超级接口的Class对象。这种引用一定是实例引用。(实际上,超类、超级接口的引用也存储在常量池中,但为了区分依赖类的引用,将它特殊表述一下。)
因此,我暂且得到两条结论。
结论一:持有一个Class对象的引用,则任何该Class对象直接或间接依赖的所有类(如果被加载了),都不可能被卸载。同样,只要有一个类直接或间接依赖某个类,则该类不可能被卸载。
结论二:持有一个Class对象的引用,则该类的所有超类、超接口都不能被卸载。同样,如果任何一个类(或接口)存在一个没有被卸载的子类(或实现类、子接口),则该类(接口)不可能被卸载。
由此可见,对于一个软件而言,其所有class文件可以看做一个从包含main方法的根节点出发,在一张依赖图中搜索所有可达节点,所有可达节点构成的集合。而这个集合中的绝大部分类,要么全部保留在内存中,要么全部卸载。
对于一个模块而言,如果该模块之间的类彼此都存在依赖,则该模块必须整个地被卸载。因此,如果一个应用程序想要利用一个模块卸载另外一个模块。必要条件就是,执行卸载操作的模块必须零依赖被卸载的模块。
零依赖的含义就是,被依赖的模块是完全透明的,是不可见的。
根据上面的结论,卸载必须是以模块为单位。因此,所谓卸载一个强耦合的类是完全不可能的。因此,我可以放弃说“卸载类”,而应该说“卸载模块”。
那么,卸载一个模块的充分条件是什么呢?
回到前面的那张引用关系图,让我们来看看那些其他要素可能引用Class对象。
对于任何一个Java对象而言,它都一定是某个类的实例,因此,它能直接或间接的引用到该类的Class对象。这一推论的理由有三,其一,JVM在将对象进行向下转型、instanceof判定的时候,一定要知道对象的类型,倘若对象无法引用到类的Class对象,这个过程何以进行呢?其二,子类可重写父类的方法,运行时的多态令虚拟机能正确调用到对象方法(防止子类调用到父类被覆盖的方法),如果不知对象类型,何以实现?其三,Object类有一个native方法getClass()可以直接获取对象的类Class对象。
类加载器在加载了一个类之后,当第二次接受到该类的类名之后,加载器会直接返回该类的对象,而不是重复加载该类。虚拟机绝不允许同一个命名空间中的一个类被加载了两次,因此类加载器必须缓存所有它加载的类的Class对象,以供返回。
此外,ClassLoader也好,Class对象也好,这些本身能被变量所引用。如果某些可达的变量(局部变量、成员变量、静态变量)引用了它们,自然也会让整个模块变得可达而无法被卸载。
此外,某些特殊的类加载器永远是可达的,它们是Bootstrap、Extendsion、System。因此,我可以得出一条结论。
结论三:Java的标准类库一旦加载,永远不能卸载。
结论四:CLASS_PATH中的类(系统加载器加载的类),一旦加载,永远不能被卸载。
因此,一个模块中的所有类必须使用同一个ClassLoader实例加载。而且这个ClassLoader实例不能是Extendsion和System。这个ClassLoader实例的控制权必须掌握在操作卸载的模块那里。随时释放该实例的引用,使ClassLoader变得不可达。
此外,该模块任意类的实例都必须是不可达的,存在任何一个可达的该模块类的实例,模块都无法释放。
至此,我得到了卸载模块的充分条件:模块的全部类由一个可控的ClassLoader加载;释放该模块的定义类加载器引用;释放该模块所有类的实例引用;释放该模块的Class对象引用。
还有,模块的定义类加载器、类实例、Class对象,这些东西,只要没有引用掌握在其他模块那里,也没有掌握在栈内存中,就一定可以卸载模块。特别的,模块自己引用了这些东西,尤其是模块的静态变量引用了这些东西,那是完全不影响卸载的。
有一种观点认为,垃圾回收判断的根节点包括所有类的静态变量,这是错误的。实际上如果一个模块变得不可达了,它的所有的类的静态变量也会变得不可达,并会被回收释放。
转自:
http://taozeyu.com/software/2014/03/15/jvm-class-loader-2.html
【转】JVM类装载机制的解析,热更新的探讨(二)的更多相关文章
- 【转】JVM类装载机制的解析,热更新的探讨
引言 如有错误,请批评指正. Java是一种动态连接的语言.所谓动态连接,大概可以这么解释. 首先,Java可以大概想象成是编译解释执行的.对于一个*.java的文件,通过javac将会编译成一个*. ...
- 深入研究Java类装载机制
目录 1.为什么要研究java类装在机制? 2.了解类装载机制,对于我们在项目开发中有什么作用? 3.装载实现细节. 4.总结 一.为什么药研究Java类装载机制 java类加载机制,便于我们使用自定 ...
- JVM的类加载机制全面解析
什么是类加载机制 JVM把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这就是JVM的类加载机制. 如果你对Class文件的结 ...
- 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (二)
上次讲解了FairyGUI的最简单的热更新办法,并对其中一个Demo进行了修改并做成了热更新的方式. 这次我们来一个更加复杂一些的情况:Emoji. FairyGUI的 Example 04 - ...
- Unity热更新学习(二) —— ToLua c#与lua的相互调用
tolua 下载地址:http://www.ulua.org/index.html c#调用lua的方法,tolua的官方例子提供了很多种.我初步学了一种在做项目使用的方法.通过DoFile方法执行l ...
- Unity3D热更新全书-脚本(二) 两级分化
上篇明确了我们探讨的脚本是什么:是写在文本文件里面的代码,可以作为资源加载,取得字符串再执行. 可是为什么世界上会有那么多的脚本?而其使用方法完全看起来不一样呢?这是因为每种脚本都有自己的定位,在不同 ...
- Unity手游之路<十二>手游资源热更新策略探讨
http://blog.csdn.net/janeky/article/details/17666409 上一次我们学习了如何将资源进行打包.这次就可以用上场了,我们来探讨一下手游资源的增量更新策略. ...
- [unity3d]手游资源热更新策略探讨
原地址:http://blog.csdn.net/dingxiaowei2013/article/details/20079683 我们学习了如何将资源进行打包.这次就可以用上场了,我们来探讨一下手游 ...
- [转]Unity手游之路<十二>手游资源热更新策略探讨
最近梳理了下游戏流程.恩,本来想写下,但是,还是看前辈的吧 版权声明: https://blog.csdn.net/janeky/article/details/17666409 上一次我们学习了如何 ...
随机推荐
- iOS 简化冗余代码
正在给深圳某家智能家居开发iPad版本,在已经存在的iPhone版上修改,该app的界面采用的是xib.xib相比代码来写界面,快速高效,但是可维护性和可读性太差.言归正传,看到这些代码后,我的心情很 ...
- SAP云平台里的三叉戟应用
大家第一次看到SAP MTA这个词组,会联想到什么? Jerry第一次看到的时候,联想到的是那一个个足坛著名的三叉戟攻击组合. 海皇波塞冬(Poseidon),奥林匹斯十二神中地位仅次于宙斯的大神,海 ...
- Http状态吗504问题复盘
原因分析:504错误一般与nginx.conf配置有关,主要参数有:fastcgi_connect_timeout.fastcgi_send_timeout.fastcgi_read_timeout. ...
- MySQL DataType--日期格式
在MySQL中,无论是字符串转换为时间还是时间转换为字符串,都需要使用到时间格式: %a 缩写星期名 %b 缩写月名 %c 月,数值 %D 带有英文前缀的月中的天 %d 月的天,数值(00-31) % ...
- MySQL查询(关联查询)
一.mysql查询与权限 (一)数据库关联查询 **内连接查询(inner join)** 查询两个表共有的数据,交集 SELECT * FROM tb1 INNER JOIN tb2 ON 条件 所 ...
- IDEA -01 -忽略指定文件夹 -防止加载Vue-cli执行"npm install"命令后的项目时卡死
问题描述 Vue的"npm install" 命令执行后,会生成一个很大的目录层次的"node_modules",文件十分繁多; idea加载这个项目下的文件夹 ...
- 创建型模式(三) 抽象工厂模式(Abstract Factory)
一.动机(Motivation) 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时,由于需求的变化,往往存在更多系列对象的创建工作. 如何应对这种变化?如何绕过常规的对象创建方法(ne ...
- 【IT】在线技术工具
1.IP地址查询: (1)http://www.ip138.com/ 注:可查询此IP地址的服务器归属地 (2)https://x.threatbook.cn/ 注:可查询域名.ip等的反查域名 2.
- “只有DBA才能导入由其他DBA导出的文件”各种解决办法
“只有DBA才能导入由其他DBA导出的文件”各种解决办法 当oracle导入的时候出现“只有 DBA 才能导入由其他 DBA 导出的文件”的时候通常有以下几种解决办法! 1:常见的是直接grant ...
- Coins in a Line I
Description There are n coins with different value in a line. Two players take turns to take one or ...