Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
清新范er
JavaGuide
提交
aee190f0
J
JavaGuide
项目概览
清新范er
/
JavaGuide
与 Fork 源项目一致
从无法访问的项目Fork
通知
4
Star
0
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,发现更多精彩内容 >>
未验证
提交
aee190f0
编写于
3月 25, 2021
作者:
G
Guide哥
提交者:
GitHub
3月 25, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1136 from JoeMinty/patch-4
Update 类加载过程.md
上级
ccdea6cf
da93026f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
5 addition
and
5 deletion
+5
-5
docs/java/jvm/类加载过程.md
docs/java/jvm/类加载过程.md
+5
-5
未找到文件。
docs/java/jvm/类加载过程.md
浏览文件 @
aee190f0
...
...
@@ -23,7 +23,7 @@
Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢?
系统加载 Class 类型的文件主要三步
:
**加载->连接->初始化**
。连接过程又可分为三步:
**验证->准备->解析**
。
系统加载 Class 类型的文件主要三步
:
**加载->连接->初始化**
。连接过程又可分为三步:
**验证->准备->解析**
。
![](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png
)
...
...
@@ -33,7 +33,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
1.
通过全类名获取定义此类的二进制字节流
2.
将字节流所代表的静态存储结构转换为方法区的运行时数据结构
3.
在内存中生成一个代表该类的 Class 对象
,
作为方法区这些数据的访问入口
3.
在内存中生成一个代表该类的 Class 对象
,
作为方法区这些数据的访问入口
虚拟机规范上面这3点并不具体,因此是非常灵活的。比如:"通过全类名获取定义此类的二进制字节流" 并没有指明具体从哪里获取、怎样获取。比如:比较常见的就是从 ZIP 包中读取(日后出现的JAR、EAR、WAR格式的基础)、其他文件生成(典型应用就是JSP)等等。
...
...
@@ -70,7 +70,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
初始化是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行初始化方法
`<clinit> ()`
方法的过程。
对于
`<clinit>
()`
方法的调用,虚拟机会自己确保其在多线程环境中的安全性。因为
`<clinit>()
`
方法是带锁线程安全,所以在多线程环境下进行类初始化的话可能会引起死锁,并且这种死锁很难被发现。
对于
`<clinit>
()`
方法的调用,虚拟机会自己确保其在多线程环境中的安全性。因为
`<clinit> ()
`
方法是带锁线程安全,所以在多线程环境下进行类初始化的话可能会引起死锁,并且这种死锁很难被发现。
对于初始化阶段,虚拟机严格规范了有且只有5种情况下,必须对类进行初始化(只有主动去使用类才会初始化类):
...
...
@@ -79,7 +79,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
-
当jvm执行getstatic指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。
-
当jvm执行putstatic指令时会初始化类。即程序给类的静态变量赋值。
-
当jvm执行invokestatic指令时会初始化类。即程序调用类的静态方法。
2.
使用
`java.lang.reflect`
包的方法对类进行反射调用时如Class.forname("..."),
newInstance()等等。 ,
如果类没初始化,需要触发其初始化。
2.
使用
`java.lang.reflect`
包的方法对类进行反射调用时如Class.forname("..."),
newInstance()等等。
如果类没初始化,需要触发其初始化。
3.
初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。
4.
当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。
5.
MethodHandle和VarHandle可以看作是轻量级的反射调用机制,而要想使用这2个调用,
...
...
@@ -100,7 +100,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
所以,在JVM生命周期类,由jvm自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。
只要想通一点就好了,jdk自带的BootstrapClassLoader,
ExtClassLoader,
AppClassLoader负责加载jdk提供的类,所以它们(类加载器的实例)肯定不会被回收。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。
只要想通一点就好了,jdk自带的BootstrapClassLoader,
ExtClassLoader,
AppClassLoader负责加载jdk提供的类,所以它们(类加载器的实例)肯定不会被回收。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。
**参考**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录