Skip to content

Commit 7c04b96

Browse files
committed
no message
1 parent 5a0014c commit 7c04b96

1 file changed

Lines changed: 32 additions & 18 deletions

File tree

notes/JavaArchitecture/05 Java 虚拟机.md

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
- [7. G1](#7-g1)
4343
- [8. 比较](#8-比较)
4444
- [5. 内存分配与回收策略](#5-内存分配与回收策略)
45-
- [1. 什么时候进行MinGC,FullGC](#1-什么时候进行mingcfullgc)
45+
- [1. 什么时候进行Minor GC,Full GC](#1-什么时候进行minor-gcfull-gc)
4646
- [2. 内存分配策略](#2-内存分配策略)
4747
- [1. 对象优先在 Eden 分配](#1-对象优先在-eden-分配)
4848
- [2. 大对象直接进入老年代](#2-大对象直接进入老年代)
@@ -124,7 +124,7 @@ Class Files -> ClassLoader -> 运行时数据区 -> 执行引擎,本地库接
124124

125125
## JVM体系结构
126126

127-
虚拟机是物理机器的软件实现。Java 的开发遵循 write once run anywhere(一次编写到处乱跑)理念,它运行在VM(虚拟机)上。编译器将 Java 文件编译成 Java.class 文件,之后,将 .class 文件输入到 JVM 中,加载并执行该类文件。下图是JVM 的体系结构
127+
虚拟机是物理机器的软件实现。Java 的开发遵循 write once run anywhere(一次编写到处乱跑)理念,它运行在 VM(虚拟机)上。编译器将 Java 文件编译成 Java.class 文件,之后,将 .class 文件输入到 JVM 中,加载并执行该类文件。下图是 JVM 的体系结构
128128

129129
![img](assets/435918-20180701233830808-854564995.png)
130130

@@ -263,6 +263,10 @@ java -Xss=512M HackTheJava
263263

264264

265265

266+
栈帧详解:[虚拟机中的运行时栈帧 - kosamino - 博客园](https://www.cnblogs.com/jing99/p/6076102.html)
267+
268+
269+
266270

267271
### 3. 本地方法栈(线程私有)
268272

@@ -367,9 +371,9 @@ System.out.println(s1 == s1); // true
367371

368372
### 1. 引用计数算法
369373

370-
**描述**给对象中添加一个引用计数器每当有一个地方引用它时,计数器就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能在被使用的。
374+
**描述**给对象中添加一个引用计数器每当有一个地方引用它时,计数器就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能在被使用的。
371375

372-
**缺陷**很难解决对象间相互循环引用的问题
376+
**缺陷**很难解决对象间相互循环引用的问题
373377

374378

375379

@@ -518,8 +522,8 @@ HotSpot 虚拟机的 Eden 和 Survivor 的大小比例默认为 8:1,保证了
518522

519523
一般将堆分为新生代和老年代。
520524

521-
- 新生代使用:复制算法
522-
- 老年代使用:标记 - 清除 或者 标记 - 整理 算法
525+
- 新生代使用:**复制回收** 算法
526+
- 老年代使用:**标记 - 清除** 或者 **标记 - 整理** 算法
523527

524528

525529

@@ -638,18 +642,18 @@ Parallel Old 是 Parallel Scavenge 收集器的老年代版本,使用多线程
638642

639643
![](../pics/cms.png)
640644

641-
CMS(Concurrent Mark Sweep),Mark Sweep 指的是 标记 - 清除 算法。CMS 是一款优秀的收集器,主要优点:并发收集、低停顿,Sun公司也称之为**并发低停顿收集器**(Concurrent Low Pause Collection)。
645+
CMS(Concurrent Mark Sweep),Mark Sweep 指的是 **标记 - 清除** 算法。CMS 是一款优秀的收集器,主要优点:并发收集、低停顿,Sun公司也称之为**并发低停顿收集器**(Concurrent Low Pause Collection)。
642646

643647
特点:并发收集、低停顿。
644648

645649
分为以下四个流程:
646650

647651
- 初始标记:仅仅只是标记一下 GC Roots 能直接关联到的对象,速度很快,需要停顿。
648-
- 并发标记:进行 GC Roots Tracing 的过程,它在整个回收过程中耗时最长,不需要停顿。
652+
- **并发标记**:进行 GC Roots Tracing 的过程,它在整个回收过程中耗时最长,不需要停顿。
649653
- 重新标记:为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,需要停顿。
650-
- 并发清除:不需要停顿。
654+
- **并发清除**:不需要停顿。
651655

652-
在整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,不需要进行停顿。
656+
在整个过程中耗时最长的**并发标记****并发清除**过程中,收集器线程都可以与用户线程一起工作,不需要进行停顿。
653657

654658
具有以下缺点:
655659

@@ -664,9 +668,9 @@ CMS(Concurrent Mark Sweep),Mark Sweep 指的是 标记 - 清除 算法。C
664668

665669
### 7. G1
666670

667-
G1的第一篇paper(附录1)发表于2004年,在2012年才在jdk1.7u4中可用。oracle官方计划在jdk9中将G1变成默认的垃圾收集器,以替代CMS
671+
G1的第一篇paper(附录1)发表于 2004 年,在 2012 年才在 jdk1.7u4 中可用。oracle 官方计划在 jdk9 中将 G1 变成默认的垃圾收集器,以替代 CMS
668672

669-
- 为何oracle要极力推荐G1呢,G1有哪些优点
673+
- 为何 oracle 要极力推荐 G1 呢,G1 有哪些优点
670674
- 首先,G1的设计原则就是简单可行的性能调优
671675
- 其次,G1将新生代,老年代的物理空间划分取消了****
672676

@@ -716,9 +720,9 @@ G1 把堆划分成多个大小相等的独立区域(Region),新生代和
716720
| 收集器 | 单线程/并行 | 串行/并发 | 新生代/老年代 | 收集算法 | 目标 | 适用场景 |
717721
| --------------------- | ----------- | --------- | --------------- | -------------------- | ------------ | --------------------------------------------- |
718722
| **Serial** | 单线程 | 串行 | 新生代 | 复制 | 响应速度优先 | 单 CPU 环境下的 Client 模式 |
719-
| **Serial Old** | 单线程 | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 |
720723
| **ParNew** | 并行 | 串行 | 新生代 | 复制算法 | 响应速度优先 | 多 CPU 环境时在 Server 模式下与 CMS 配合 |
721724
| **Parallel Scavenge** | 并行 | 串行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
725+
| **Serial Old** | 单线程 | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 |
722726
| **Parallel Old** | 并行 | 串行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
723727
| **CMS** | 并行 | 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或 B/S 系统服务端上的 Java 应用 |
724728
| **G1** | 并行 | 并发 | 新生代 + 老年代 | 标记-整理 + 复制算法 | 响应速度优先 | 面向服务端应用,将来替换 CMS |
@@ -732,7 +736,7 @@ G1 把堆划分成多个大小相等的独立区域(Region),新生代和
732736

733737
## 5. 内存分配与回收策略
734738

735-
### 1. 什么时候进行MinGC,FullGC
739+
### 1. 什么时候进行Minor GC,Full GC
736740

737741
- Minor GC:发生在新生代上,因为新生代对象存活时间很短,因此 Minor GC 会频繁执行,执行的速度一般也会比较快。
738742
- 新生代中的垃圾收集动作,采用的是复制算法
@@ -903,7 +907,7 @@ System.out.println(ConstClass.HELLOWORLD);
903907
目的:确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
904908

905909
- 文件格式验证:验证字节流是否符合 Class 文件格式的规范,并且能被当前版本的虚拟机处理。
906-
- 是否以0xCAFEBABE开头,前四个字节为魔数
910+
- 是否以 0xCAFEBABE 开头,前四个字节为魔数
907911
- 版本号是否合理,如:JDK1.8(52.0)、JDK1.7(51.0)
908912

909913
- 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合 Java 语言规范的要求。
@@ -946,7 +950,7 @@ public static final int value = 123;
946950

947951
#### 4. 解析
948952

949-
解析阶段是虚拟机将常量池的符号引用替换为直接引用的过程
953+
解析阶段是虚拟机将常量池的**符号引用替换为直接引用**的过程
950954

951955
- 类或接口的解析
952956
- 字段解析
@@ -962,6 +966,14 @@ public static final int value = 123;
962966

963967

964968

969+
符号引用就是字符串,这个字符串包含足够的信息,以供实际使用时可以找到相应的位置。你比如说某个方法的符号引用,如:“java/io/PrintStream.println:(Ljava/lang/String;)V”。里面有类的信息,方法名,方法参数等信息。
970+
971+
当第一次运行时,要根据字符串的内容,到该类的方法表中搜索这个方法。运行一次之后,符号引用会被替换为直接引用,下次就不用搜索了。直接引用就是偏移量,通过偏移量虚拟机可以直接在该类的内存区域中找到方法字节码的起始位置。
972+
973+
974+
975+
976+
965977
参考资料:
966978

967979
- [【必读】JVM 类加载机制 - 掘金](https://juejin.im/post/5a1d644551882534af25b381)
@@ -1072,7 +1084,7 @@ public static void main(String[] args) {
10721084

10731085
#### 3. 双亲委派模型
10741086

1075-
- 为什么要使用双亲委派模型?
1087+
- 为什么要使用双亲委派模型?
10761088
- 主要是为了避免重复加载的问题
10771089

10781090
JVM 如何加载一个类的过程,双亲委派模型中有哪些方法有没有可能父类加载器和子类加载器,加载同一个类?如果加载同一个类,该使用哪一个类?
@@ -1366,4 +1378,6 @@ for (int i = 1; i < 100; i++) {
13661378

13671379
v1.0 2018/7/21 初版完成
13681380

1369-
v2.4 2018/8/18 基础初版
1381+
v2.4 2018/8/18 基础初版
1382+
1383+
v2.5 2018/8/18 修改格式,补充符号链接与直接链接

0 commit comments

Comments
 (0)