【转】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 上一次我们学习了如何 ...
随机推荐
- 在Xcode4 中将iPhone使用的xib转换成iPad使用的xib
来源:http://blog.3snews.net/space.php?uid=6188&do=blog&id=64200 http://www.giser.net/?p=982 1 ...
- CRM, C4C和SAP Hybris的数据库层设计
SAP的product都是DB provider无关的. CRM大家都很熟悉了,application developer最多用Open SQL直接操作表. Netweaver里支持的DB provi ...
- mysql学习之基础篇07
视图:view 在查询的时候我们经常把查询到的结果当成一张临时表来看,其实view就可以看成一张虚拟表,是表通过某种运算得到的投影 那么如何创建视图?创建视图需要指定视图的列名和列类型吗? 答:不用, ...
- 【HICP Gauss】数据库 数据库管理(调优 启动流程)-4
数据库参数: 创建数据库 调优数据库 其他---->控制资源使用 控制数据库内部机制 设置重要属性 参数数据保存在cfg/Zengine.ini 文件中 参数保存使用 key=value的保存形 ...
- LAMP环境搭建基本步骤
LAMP环境搭建基本步骤 参考链接https://yq.aliyun.com/articles/106387 apache性能优化.配置https://my.oschina.net/lockupme/ ...
- commons-io之FileUtils、IOUtils
原文:https://blog.csdn.net/justry_deng/article/details/93616705 commons-io简单说明:Common IO 是一个工具库,用来帮助开发 ...
- LG4762 Virus synthesis
Virus synthesis 初始有一个空串,利用下面的操作构造给定串 S . 串开头或末尾加一个字符 串开头或末尾加一个该串的逆串 求最小化操作数, ∣S∣≤105 . 题解 显然应该多使用操作2 ...
- CH6302 雨天的尾巴
6302 雨天的尾巴 0x60「图论」例题 背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了 ...
- Oracle 序号函数
Oracle提供的序号函数:以emp表为例:1: rownum 最简单的序号 但是在order by之前就确定值.select rownum,t.* from emp t order by ename ...
- Django 会议室预定
表结构分析: from django.db import models # Create your models here. from django.db import models from dja ...