Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
醒狮指南
JavaGuide
提交
069fd06b
J
JavaGuide
项目概览
醒狮指南
/
JavaGuide
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
JavaGuide
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
069fd06b
编写于
2月 29, 2020
作者:
S
shuang.kou
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
类的生命周期——卸载
上级
49c1fbf0
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
30 addition
and
7 deletion
+30
-7
docs/java/jvm/类加载过程.md
docs/java/jvm/类加载过程.md
+30
-7
未找到文件。
docs/java/jvm/类加载过程.md
浏览文件 @
069fd06b
...
...
@@ -8,20 +8,27 @@
-
[
准备
](
#准备
)
-
[
解析
](
#解析
)
-
[
初始化
](
#初始化
)
-
[
扩展:类的生命周期
](
#扩展:类的生命周期
)
<!-- /TOC -->
> 公众号JavaGuide 后台回复关键字“1”,免费获取JavaGuide配套的Java工程师必备学习资源(文末有公众号二维码)。
# 类加载过程
一个类的完整生命周期如下:
![](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/类加载过程-完善.png
)
## 类加载过程
Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢?
系统加载 Class 类型的文件主要三步:
**加载->连接->初始化**
。连接过程又可分为三步:
**验证->准备->解析**
。
![
类加载过程
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png
)
![](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png
)
## 加载
##
#
加载
类加载过程的第一步,主要完成下面3件事情:
...
...
@@ -37,11 +44,11 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
加载阶段和连接阶段的部分内容是交叉进行的,加载阶段尚未结束,连接阶段可能就已经开始了。
## 验证
##
#
验证
![
验证阶段示意图
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/验证阶段.png
)
## 准备
##
#
准备
**准备阶段是正式为类变量分配内存并设置类变量初始值的阶段**
,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:
...
...
@@ -52,7 +59,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
![
基本数据类型的零值
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/基本数据类型的零值.png
)
## 解析
##
#
解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。
...
...
@@ -60,7 +67,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
综上,解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,也就是得到类或者字段、方法在内存中的指针或者偏移量。
## 初始化
##
#
初始化
初始化是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行类构造器
`<clinit> ()`
方法的过程。
...
...
@@ -74,6 +81,22 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
4.
当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。
5.
当使用 JDK1.7 的动态动态语言时,如果一个 MethodHandle 实例的最后解析结构为 REF_getStatic、REF_putStatic、REF_invokeStatic、的方法句柄,并且这个句柄没有初始化,则需要先触发器初始化。
## 卸载
> 卸载这部分内容来自 [issue#662](https://github.com/Snailclimb/JavaGuide/issues/662)由 **[guang19](https://github.com/guang19)** 补充完善。
卸载类即该类的Class对象被GC。
卸载类需要满足3个要求:
1.
该类的所有的实例对象都已被GC,也就是说堆不存在该类的实例对象。
2.
该类没有在其他任何地方被引用
3.
该类的类加载器的实例已被GC
所以,在JVM生命周期类,由jvm自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。
只要想通一点就好了,jdk自带的BootstrapClassLoader,PlatformClassLoader,AppClassLoader负责加载jdk提供的类,所以它们(类加载器的实例)肯定不会被回收。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。
**参考**
-
《深入理解Java虚拟机》
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录