Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
点击事件
JavaGuide
提交
1741a679
J
JavaGuide
项目概览
点击事件
/
JavaGuide
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
JavaGuide
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1741a679
编写于
8月 27, 2021
作者:
K
kaka2634
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update [加餐]大白话带你认识JVM.md
上级
4baeecd2
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
5 addition
and
5 deletion
+5
-5
docs/java/jvm/[加餐]大白话带你认识JVM.md
docs/java/jvm/[加餐]大白话带你认识JVM.md
+5
-5
未找到文件。
docs/java/jvm/[加餐]大白话带你认识JVM.md
浏览文件 @
1741a679
...
...
@@ -95,7 +95,7 @@ JVM 是 Java Virtual Machine 的缩写,它是一个虚构出来的计算机,
#### 2.1.3 初始化
初始化其实就是执行类构造器方法的
`<clinit>()`
的过程,而且要保证执行前父类的
`<clinit>()`
方法执行完毕。这个方法由编译器收集,顺序执行所有类变量(static修饰的成员变量)显式初始化和静态代码块中语句。此时准备阶段时的那个
`static int a`
由默认初始化的0变成了显式初始化的3
.
由于执行顺序缘故,初始化阶段类变量如果在静态代码块中又进行了更改,会覆盖类变量的显式初始化,最终值会为静态代码块中的赋值。
初始化其实就是执行类构造器方法的
`<clinit>()`
的过程,而且要保证执行前父类的
`<clinit>()`
方法执行完毕。这个方法由编译器收集,顺序执行所有类变量(static修饰的成员变量)显式初始化和静态代码块中语句。此时准备阶段时的那个
`static int a`
由默认初始化的0变成了显式初始化的3
。
由于执行顺序缘故,初始化阶段类变量如果在静态代码块中又进行了更改,会覆盖类变量的显式初始化,最终值会为静态代码块中的赋值。
>注意:字节码文件中初始化方法有两种,非静态资源初始化的`<init>`和静态资源初始化的`<clinit>`,类构造器方法`<clinit>()`不同于类的构造器,这些方法都是字节码文件中只能给JVM识别的特殊方法。
#### 2.1.4 卸载
...
...
@@ -113,11 +113,11 @@ GC将无用对象从内存中卸载
### 2.3 双亲委派机制
当一个类收到了加载请求时,它是不会先自己去尝试加载的,而是委派给父类去完成,比如我现在要
new一个Person,这个Person是我们自定义的类,如果我们要加载它,就会先委派App ClassLoader,只有当父类加载器都反馈自己无法完成这个请求(也就是父类加载器都没有找到加载所需的
Class)时,子类加载器才会自行尝试加载。
当一个类收到了加载请求时,它是不会先自己去尝试加载的,而是委派给父类去完成,比如我现在要
new 一个 Person,这个 Person 是我们自定义的类,如果我们要加载它,就会先委派 App ClassLoader ,只有当父类加载器都反馈自己无法完成这个请求(也就是父类加载器都没有找到加载所需的
Class)时,子类加载器才会自行尝试加载。
这样做的好处是,加载位于
rt.jar包中的类时不管是哪个加载器加载,最终都会委托到BootStrap ClassLoader
进行加载,这样保证了使用不同的类加载器得到的都是同一个结果。
这样做的好处是,加载位于
rt.jar 包中的类时不管是哪个加载器加载,最终都会委托到 BootStrap ClassLoader
进行加载,这样保证了使用不同的类加载器得到的都是同一个结果。
其实这个也是一个隔离的作用,避免了我们的代码影响了
JDK
的代码,比如我现在自己定义一个
`java.lang.String`
:
其实这个也是一个隔离的作用,避免了我们的代码影响了
JDK
的代码,比如我现在自己定义一个
`java.lang.String`
:
```
java
package
java.lang
;
...
...
@@ -128,7 +128,7 @@ public class String {
}
```
尝试运行当前类的
`main`
函数的时候,我们的代码肯定会报错。这是因为在加载的时候其实是找到了 rt.jar 中的
`java.lang.String`
,然而发现这个里面并没有
main
方法。
尝试运行当前类的
`main`
函数的时候,我们的代码肯定会报错。这是因为在加载的时候其实是找到了 rt.jar 中的
`java.lang.String`
,然而发现这个里面并没有
`main`
方法。
## 三、运行时数据区
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录