Skip to content

Commit 852710f

Browse files
committed
no message
1 parent 5d7b763 commit 852710f

5 files changed

Lines changed: 248 additions & 4 deletions

File tree

notes/JavaArchitecture/03 Java 并发编程.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@
9494
- [偏向锁](#偏向锁)
9595
- [13. 多线程开发良好的实践](#13-多线程开发良好的实践)
9696
- [14. 线程池实现原理](#14-线程池实现原理)
97-
- [概念](#概念)
97+
- [并发队列](#并发队列)
98+
- [线程池概念](#线程池概念)
9899
- [Executor类图](#executor类图)
99100
- [线程池工作原理](#线程池工作原理)
100101
- [初始化线程池](#初始化线程池)
@@ -2487,7 +2488,29 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:
24872488

24882489
> 蘑菇街面试,设计一个线程池
24892490

2490-
### 概念
2491+
![ThrealpoolExecutor_framework](assets/ThrealpoolExecutor_framework.jpg)
2492+
2493+
### 并发队列
2494+
2495+
**入队**
2496+
2497+
非阻塞队列:当队列中满了时候,放入数据,数据丢失
2498+
2499+
阻塞队列:当队列满了的时候,进行等待,什么时候队列中有出队的数据,那么第11个再放进去
2500+
2501+
**出队**
2502+
2503+
非阻塞队列:如果现在队列中没有元素,取元素,得到的是null
2504+
2505+
阻塞队列:等待,什么时候放进去,再取出来
2506+
2507+
2508+
2509+
线程池使用的是阻塞队列
2510+
2511+
2512+
2513+
### 线程池概念
24912514

24922515
线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:
24932516

@@ -2613,6 +2636,7 @@ ThreadPoolExecutor 提供了动态调整线程池容量大小的方法:setCore
26132636
- 参考资料
26142637
- [Java线程池的使用及原理](http://tangxiaolin.com/learn/show?id=402881d2651d1bdf01651de142df0000)
26152638
- [深入分析java线程池的实现原理 - 简书](https://www.jianshu.com/p/87bff5cc8d8c)
2639+
- [尚学堂线程池并发队列ThreadPoolExecutor_Callable原理解析哔哩哔哩 (゜-゜)つロ 干杯~-bilibili](https://www.bilibili.com/video/av26354412?p=2)
26162640

26172641

26182642

notes/JavaArchitecture/05 Java 虚拟机.md

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
- [前言](#前言)
44
- [核心知识](#核心知识)
5+
- [JVM体系结构](#jvm体系结构)
6+
- [JVM各个模块简介](#jvm各个模块简介)
7+
- [JVM是如何工作的?](#jvm是如何工作的)
58
- [1. 运行时数据区域](#1-运行时数据区域)
69
- [1. 程序计数器(线程私有)](#1-程序计数器线程私有)
710
- [2. 虚拟机栈(线程私有)](#2-虚拟机栈线程私有)
@@ -85,7 +88,6 @@
8588
- [更新说明](#更新说明)
8689

8790
<!-- /TOC -->
88-
8991
# 前言
9092

9193
在本文将深入讨论 Java 虚拟机相关核心知识
@@ -108,6 +110,120 @@
108110

109111
# 核心知识
110112

113+
- JVM 基本结构
114+
- 类加载器
115+
- 执行引擎
116+
- 运行时数据区
117+
- 本地接口
118+
119+
Class Files -> ClassLoader -> 运行时数据区 -> 执行引擎,本地库接口 -> 本地方法库
120+
121+
122+
123+
124+
125+
## JVM体系结构
126+
127+
虚拟机是物理机器的软件实现。Java 的开发遵循 write once run anywhere(一次编写到处乱跑)理念,它运行在VM(虚拟机)上。编译器将 Java 文件编译成 Java.class 文件,之后,将 .class 文件输入到 JVM 中,加载并执行该类文件。下图是JVM 的体系结构
128+
129+
![img](assets/435918-20180701233830808-854564995.png)
130+
131+
132+
133+
### JVM各个模块简介
134+
135+
1. 运行时数据区:经过编译生成的字节码文件(class文件),由 class loader(类加载子系统)加载后交给执行引擎执行。在执行引擎执行的过程中产生的数据会存储在一块内存区域。这块内存区域就是运行时区域
136+
137+
2. 程序计数器:用于记录当前线程的正在执行的字节码指令位置。由于虚拟机的多线程是切换线程并分配 cpu 执行时间的方式实现的,不同线程的执行位置都需要记录下来,因此程序计数器是线程私有的
138+
139+
3. 虚拟机栈:虚拟机栈是 Java 方法执行的内存结构,虚拟机会在每个 Java 方法执行时创建一个“栈桢”,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。当方法执行完毕时,该栈桢会从虚拟机栈中出栈。其中局部变量表包含基本数据类型和对象引用
140+
- 在 Java 虚拟机规范中,对这个区域规定了两种异常状态:如果线程请求的栈的深度大于虚拟机允许的深度,将抛出 StackOverFlowError 异常(栈溢出),如果虚拟机栈可以动态扩展(现在大部分 Java 虚拟机都可以动态扩展,只不过 Java 虚拟机规范中也允许固定长度的 Java 虚拟机栈),如果扩展时无法申请到足够的内存空间,就会抛出 OutOfmMemoryError 异常(没有足够的内存)
141+
142+
4. 本地方法栈:类似 Java 方法的执行有虚拟机栈,本地方法的执行则对应有本地方法栈
143+
144+
5. 方法区:用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。线程共享(看存储的数据就知道了)
145+
146+
6. Java 堆(Heap):堆的主要作用是存放程序运行过程中创建的对象实例,因为要存放的对象实例有可能会极多,因此也是虚拟机内存管理中最大的一块。并且由于硬件条件有限,所以需要不断回收已“无用”的实例对象来腾出空间给新生成的实例对象;因此 Java 的垃圾回收主要是针对堆进行回收的(还有方法区的常量池),Java 堆很多时候也被称为GC堆(Garbage Collected Heap)。
147+
148+
7. 类加载机制(Class Loader):类加载子系统是根据一个类的全限定名来加载该类的二进制流到内存中,在JVM 中将形成一份描述 Class 结构的元信息对象(方法区),通过该元信息对象可以获知 Class 的结构信息:如构造函数,属性和方法等,Java 允许用户借由这个 Class 相关的元信息对象间接调用 Class 对象的功能。
149+
150+
151+
152+
153+
154+
### JVM是如何工作的?
155+
156+
如上面的体系结构图所示,JVM 分为三个主要的子系统:
157+
158+
1. 类加载器子系统
159+
2. 运行时数据区
160+
3. 执行引擎
161+
162+
163+
164+
**1、类加载器子系统**
165+
166+
Java的动态类加载功能是由类加载器子系统处理的。它负责加载、链接,并且在**运行时**首次引用类的时候初始化类,而不是在编译期间。
167+
168+
**1.1、加载**
169+
170+
这个组件负责加载类。BootStrap类加载器、Extension类加载器和Application类加载器是实现这个功能的三大类加载器。
171+
172+
1. **BootStrap类加载器** —— 负责从classpath加载类,如果没有类存在,将只加载**rt.jar**。这个加载器的优先级最高。
173+
2. **Extension类加载器** —— 负责加载**扩展文件夹(jre\lib)**中的类。
174+
3. **Application类加载器** —— 负责加载**应用级classpath**和环境变量指向的路径下的类。
175+
176+
上述**类加载器**在加载类文件时遵循**委托层次结构算法**
177+
178+
**1.2、链接**
179+
180+
1. **校验** —— 字节码验证器将校验生成的字节码是否正确,如果校验失败,我们将获得**校验错误信息**
181+
2. **准备** —— 对于所有的静态变量,内存将被申请并分配默认值。
182+
3. **解析** —— 所有**标记的内存引用****方法区域**被替换成的**原始引用**
183+
184+
**1.3、初始化**
185+
186+
这是类加载的最后阶段,所有的静态变量都将被分配原值,静态代码块将被执行。
187+
188+
189+
190+
运行时数据区
191+
192+
运行时数据区被划分为五个主要部分:
193+
194+
- **方法区** —— 所有**类级数据**都将存储在这里,包括**静态变量**。每一个JVM只有一个方法区,并且它是一个共享资源。
195+
- **堆区** —— 所有**对象**及其对应的**实例变量****数组**等存储在此,每个JVM同样只有一个堆区。由于**方法区****堆区**是多线程内存共享,因此存储的数据是非线程安全的。
196+
- **栈区** —— 每个线程都会创建一个单独的**运行时栈**。在每一次**方法调用**,都会在栈内存中创建一个**栈帧(Stack Frame)**。所有**局部变量**将在栈内存中创建。栈区是线程安全的,因为它不是一个共享资源。栈帧可以被划分为三个实体:
197+
198+
> **局部变量数组** —— 与方法中有多少局部变量有关,相应的值将存储在此处。
199+
> **操作数栈** —— 如果任何的中间操作需要被执行,**操作数栈**将作为运行时工作区来执行操作。
200+
> **帧数据** —— 与方法相对应的所有符号存储在此。在任何异常情况下,catch块的信息被保留在帧数据中。
201+
202+
- **PC寄存器** —— 每一个线程都有单独的**PC寄存器**,一旦执行指令,PC寄存器将被下一条指令**更新**,保存当前**执行指令**的地址。
203+
- **本地方法栈** —— 本地方法栈保存本地方法信息,每一个线程都会创建一个单独的本地方栈。
204+
205+
206+
207+
**3、执行引擎**
208+
209+
分配到运行时数据区的字节码将被执行引擎执行。执行引擎读取字节码并逐一执行。
210+
211+
- **解释器** —— 解释器能更加快速地解释字节码,但是执行缓慢。解释器的缺点是当多次调用一个方法时,每次都要重新解释。
212+
- **JIT编译器** —— JIT编译器弥补了解释器的不足。执行引擎使用解释器来转换字节码,当它发现重复的代码时,它将使用JIT编译器来编译整个字节码并转换为本地代码。本地代码将直接被重复的方法所调用,从而提高系统性能。
213+
- **中间代码生成器** —— 生成中间代码。
214+
- **代码优化器** —— 负责优化上述生成的中间代码。
215+
- **目标代码生成器** —— 负责生成机器码或者本地代码。
216+
- **分析器** —— 一个特殊的组件,负责查找热点代码,比如一个方法是否被调用多次。
217+
- **垃圾回收器** —— 回收并删除未引用的对象。可以通过调用**System.gc()**来触发垃圾回收,但不能保证它执行。JVM的垃圾回收是回收被创建的对象。
218+
219+
**Java本地接口(JNI)****JNI****本地方法库**交互,并为执行引擎提供**本地方法库**
220+
221+
**本地方法库(Native Method Libraries)**:它是执行引擎所需的本地库集合。
222+
223+
224+
225+
226+
111227
## 1. 运行时数据区域
112228

113229
<div align="center"> <img src="assets/540631a4-6018-40a5-aed7-081e2eeeaeea.png" width="500"/> </div><br>
@@ -856,6 +972,10 @@ public static final int value = 123;
856972

857973
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段即虚拟机执行类构造器 \<clinit>() 方法的过程。
858974

975+
976+
977+
978+
859979
在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。
860980

861981
\<clinit>() 方法具有以下特点:
@@ -952,6 +1072,9 @@ public static void main(String[] args) {
9521072

9531073
#### 3. 双亲委派模型
9541074

1075+
- ​ 为什么要使用双亲委派模型?
1076+
- 主要是为了避免重复加载的问题
1077+
9551078
JVM 如何加载一个类的过程,双亲委派模型中有哪些方法有没有可能父类加载器和子类加载器,加载同一个类?如果加载同一个类,该使用哪一个类?
9561079

9571080
- **双亲委派机制图**
@@ -1225,7 +1348,13 @@ for (int i = 1; i < 100; i++) {
12251348
- [咕泡学院-James老师_腾讯课堂](https://ke.qq.com/teacher/2904270631)
12261349
- [Java虚拟机概述和基本概念](https://centmeng.github.io/2017/03/30/Java%E6%9E%B6%E6%9E%84%E5%B8%88-JVM/)
12271350
- [JVM性能监控工具 - 简书](https://www.jianshu.com/p/25e94a1399a0)
1228-
1351+
1352+
- [探索JVM底层奥秘ClassLoader源码分析与案例讲解_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili](https://www.bilibili.com/video/av17748750?from=search&seid=7485294466500539956)
1353+
1354+
- [一个“Hello World”理解JVM运行时数据区 - 西楼有酒 - 博客园](https://www.cnblogs.com/JunFengChan/p/9250585.html)
1355+
1356+
- [JVM体系结构讲解](https://zhuanlan.zhihu.com/p/28347393)
1357+
12291358

12301359

12311360

154 KB
Loading
65.8 KB
Loading

notes/架构师成长之路.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# 架构师之路
2+
3+
目前在市面上还没有一本能够将全栈技术做一个完整的著作,计划半年时间完成《架构师之路》(拟定)一著。个人能力有限,在这里不可能将所有的技术点面面俱到,保持最简洁的方式解读。可能不能让你学到所有的技能,但我会推荐一些学习的方法和著作更好的帮助在每个技术栈上快速学习,架构师成长路上的你我。
4+
5+
有道无术,术上可求。希望笔者对于计算机的一些见闻能够帮助初出茅庐的计算机爱好者。
6+
7+
8+
9+
## 第一篇 核心技术基础
10+
11+
- 数据结构与算法
12+
- 数据结构
13+
- 算法
14+
15+
- 计算机网络
16+
- http与https
17+
- 传输层、网络层
18+
- web网络安全
19+
20+
- Linux与操作系统原理
21+
- Linux命令
22+
- 进程与线程通信
23+
24+
- 数据库
25+
- MySQL
26+
- Redis
27+
- SQL
28+
29+
30+
31+
## 第二篇 语言基础
32+
33+
- Java
34+
35+
- C++
36+
37+
- Python
38+
39+
- PHP
40+
41+
- 语言的趋势与发展
42+
43+
44+
45+
## 第三篇 高效工具
46+
47+
- Git 与 SVN
48+
- Sourcetree
49+
50+
- 高效的开发工具
51+
- sublime
52+
- Visual Studio Code
53+
- IntelliJ IDEA
54+
- Pycharm
55+
- Navicat Premium
56+
- MobaXterm / SecureCRT 8.3
57+
- 调试工具
58+
- fiddler
59+
- postman
60+
- 团队协作工具
61+
- Teambition
62+
- 博客撰写
63+
- markdown
64+
65+
66+
67+
## 第四篇 全栈增长
68+
69+
- 前端技术栈
70+
- 人人都是产品经理
71+
- APP是如何开发的
72+
- UI设计
73+
74+
75+
76+
## 第五篇 进阶技术
77+
78+
- 设计模式
79+
80+
- 经典机器学习算法
81+
82+
- 微服务从设计到部署
83+
84+
- 分布式系统演进
85+
86+
87+
88+
## 第六篇 实战应用
89+
90+
- 大并发大流量带来的问题
91+
- 海量数据处理

0 commit comments

Comments
 (0)