Skip to content

Commit

Permalink
www.wailian.work/images -> s0.wailian.download
Browse files Browse the repository at this point in the history
  • Loading branch information
T5750 committed Nov 13, 2021
1 parent 931082c commit 2e92591
Show file tree
Hide file tree
Showing 32 changed files with 64 additions and 63 deletions.
3 changes: 2 additions & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
sphinx-markdown-tables
sphinx-markdown-tables
docutils<0.18
2 changes: 1 addition & 1 deletion doc/source/jdk7/keyword/atomicOperation.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ CPU流水线 | CPU pipeline | CPU流水线的工作方式就象工业生产上
锁机制保证了只有获得锁的线程能够操作锁定的内存区域。JVM内部实现了很多种锁机制,有偏向锁,轻量级锁和互斥锁,有意思的是除了偏向锁,JVM实现锁的方式都用到的循环`CAS`,当一个线程想进入同步块的时候使用循环`CAS`的方式来获取锁,当它退出同步块的时候使用循环`CAS`释放锁。

### `concurrent`包的实现示意图
![concurrent-min](https://www.wailian.work/images/2018/10/23/concurrent-min.png)
![concurrent-min](https://s0.wailian.download/2018/10/23/concurrent-min.png)

### `CAS`应用场景
- 自旋锁
Expand Down
6 changes: 3 additions & 3 deletions doc/source/jdk7/keyword/synchronized.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ JVM是通过进入、退出对象监视器(`Monitor`)来实现对方法、同步

而对于没有获取到锁的线程将会阻塞到方法入口处,直到获取锁的线程`monitor.exit`之后才能尝试继续获取锁。

![synchronized-min](https://www.wailian.work/images/2018/10/23/synchronized-min.png)
![synchronized-min](https://s0.wailian.download/2018/10/23/synchronized-min.png)

### 锁优化
`synchronized`很多都称之为重量锁,JDK1.6中对`synchronized`进行了各种优化,为了能减少获取和释放锁带来的消耗引入了偏向锁和轻量锁。
Expand All @@ -33,7 +33,7 @@ JVM是通过进入、退出对象监视器(`Monitor`)来实现对方法、同步
- 认为大多数锁在整个同步周期都不存在竞争,所以使用`CAS`比使用互斥开销更少。
- 但如果锁竞争激烈,轻量锁就不但有互斥的开销,还有`CAS`的开销,甚至比重量锁更慢。

![轻量级锁-min](https://www.wailian.work/images/2018/10/23/-min62638.png)
![轻量级锁-min](https://s0.wailian.download/2018/10/23/-min62638.png)

#### 偏向锁
为了进一步的降低获取锁的代价,JDK1.6之后还引入了偏向锁。
Expand All @@ -47,7 +47,7 @@ JVM是通过进入、退出对象监视器(`Monitor`)来实现对方法、同步

偏向锁可以提高带有同步却没有竞争的程序性能,但如果程序中大多数锁都存在竞争时,那偏向锁就起不到太大作用。可以使用`-XX:-userBiasedLocking=false`来关闭偏向锁,并默认进入轻量锁。

![偏向锁的撤销-min](https://www.wailian.work/images/2018/10/23/-min.png)
![偏向锁的撤销-min](https://s0.wailian.download/2018/10/23/-min.png)

#### 适应性自旋
在使用`CAS`时,如果操作失败,`CAS`会自旋再次尝试。由于自旋是需要消耗CPU资源的,所以如果长期自旋就白白浪费了CPU。JDK1.6加入了适应性自旋:
Expand Down
2 changes: 1 addition & 1 deletion doc/source/jdk7/keyword/volatile.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
线程在工作时,需要将主内存中的数据拷贝到工作内存中。这样对数据的任何操作都是基于工作内存(效率提高),并且不能直接操作主内存以及其他线程工作内存中的数据,之后再将更新之后的数据刷新到主内存中。
>这里所提到的主内存可以简单认为是**堆内存**,而工作内存则可以认为是**栈内存**
![mem-min](https://www.wailian.work/images/2018/10/23/mem-min.png)
![mem-min](https://s0.wailian.download/2018/10/23/mem-min.png)

所以,在并发运行时,可能会出现线程B所读取到的数据是线程A更新之前的数据。显然这肯定是会出问题的,因此`volatile`的作用出现了:
>当一个变量被`volatile`修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据。
Expand Down
2 changes: 1 addition & 1 deletion doc/source/jdk7/lang/ThreadLocal.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## ThreadLocal

![ThreadLocal](https://www.wailian.work/images/2018/10/16/ThreadLocal.png)
![ThreadLocal](https://s0.wailian.download/2018/10/16/ThreadLocal.png)

- `ThreadLocal`类中维护`ThreadLocalMap`,用于存储每个线程的变量副本。`ThreadLocalMap``Entry`的键为线程对象,而值为对应线程的变量副本,`Entry(ThreadLocal k, Object v)`。采用空间换时间。
- `ThreadLocal`不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点:
Expand Down
10 changes: 5 additions & 5 deletions doc/source/jdk7/util/HashMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
### Base 1.7
- `HashMap`底层是基于`数组+链表`组成的。1.7`HashMap`结构图:

![HashMap1.7-min](https://www.wailian.work/images/2018/10/16/HashMap1.7-min.jpg)
![HashMap1.7-min](https://s0.wailian.download/2018/10/16/HashMap1.7-min.jpg)
```
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 // Step 1
Expand Down Expand Up @@ -170,7 +170,7 @@ final Entry<K,V> getEntry(Object key) {
- 因此1.8中重点优化了这个查询效率。1.8`HashMap`结构图:

![HashMap1.8-min](https://www.wailian.work/images/2018/10/16/HashMap1.8-min.jpg)
![HashMap1.8-min](https://s0.wailian.download/2018/10/16/HashMap1.8-min.jpg)

核心成员变量和1.7大体上都差不多,还是有几个重要的区别:
- `TREEIFY_THRESHOLD`用于判断是否需要将链表转换为红黑树的阈值。
Expand Down Expand Up @@ -273,7 +273,7 @@ for (int i = 0; i < 1000; i++) {
```
`HashMap`扩容的时候会调用`resize()`方法,就是这里的并发操作容易在一个桶上形成环形链表;这样当获取一个不存在的`key`时,计算出的index正好是环形链表的下标就会出现死循环。如下图:

![EndlessLoop-min](https://www.wailian.work/images/2018/10/16/EndlessLoop-min.jpg)
![EndlessLoop-min](https://s0.wailian.download/2018/10/16/EndlessLoop-min.jpg)

### 遍历方式
`HashMap`的遍历方式,通常有以下几种:
Expand All @@ -299,7 +299,7 @@ Iterator<String> iterator = map.keySet().iterator();
### Base 1.7
1.7由`Segment`数组、`HashEntry`组成,和`HashMap`一样,仍然是`数组+链表`。1.7`ConcurrentHashMap`结构图:

![ConcurrentHashMap1.7-min](https://www.wailian.work/images/2018/10/16/ConcurrentHashMap1.7-min.jpg)
![ConcurrentHashMap1.7-min](https://s0.wailian.download/2018/10/16/ConcurrentHashMap1.7-min.jpg)

核心成员变量:
```
Expand Down Expand Up @@ -512,7 +512,7 @@ public V get(Object key) {
### Base 1.8
1.8`ConcurrentHashMap`结构图:

![ConcurrentHashMap1.8-min](https://www.wailian.work/images/2018/10/17/ConcurrentHashMap1.8-min.jpg)
![ConcurrentHashMap1.8-min](https://s0.wailian.download/2018/10/17/ConcurrentHashMap1.8-min.jpg)

其中抛弃了原有的`Segment`分段锁,而采用了`CAS+synchronized`来保证并发安全性。
```
Expand Down
2 changes: 1 addition & 1 deletion doc/source/jdk7/util/LinkedHashMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ private static class Entry<K,V> extends HashMap.Entry<K,V> {
```
其中`Entry`继承于`HashMap``Entry`,并新增了上下节点的指针,也就形成了双向链表。利用了头节点和其余的各个节点之间通过`Entry`中的`after``before`指针进行关联。

![LinkedHashMap-min](https://www.wailian.work/images/2018/10/19/LinkedHashMap-min.jpg)
![LinkedHashMap-min](https://s0.wailian.download/2018/10/19/LinkedHashMap-min.jpg)

![LinkedHashMap2](https://s1.wailian.download/2019/12/31/LinkedHashMap2-min.png)

Expand Down
2 changes: 1 addition & 1 deletion doc/source/jdk7/util/TreeMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ SortedMap<K, V> tailMap(K fromInclusive)
```

### 2.数据结构
![TreeMap-min](https://www.wailian.work/images/2018/10/29/TreeMap-min.jpg)
![TreeMap-min](https://s0.wailian.download/2018/10/29/TreeMap-min.jpg)

1. `TreeMap`实现继承于`AbstractMap`,并且实现了`NavigableMap`接口。
1. `TreeMap`的本质是R-B Tree(红黑树),它包含几个重要的成员变量:`root`,`size`,`comparator`
Expand Down
2 changes: 1 addition & 1 deletion doc/source/jdk7/util/concurrent/CountDownLatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

`CountDownLatch`是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

![CountDownLatch-min](https://www.wailian.work/images/2018/10/17/CountDownLatch-min.png)
![CountDownLatch-min](https://s0.wailian.download/2018/10/17/CountDownLatch-min.png)

`CountDownLatch`类只提供了一个构造器:
```
Expand Down
6 changes: 3 additions & 3 deletions doc/source/jdk7/util/concurrent/ThreadPoolExecutor.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- 解耦作用;线程的创建与执行完全分开,方便维护。
- 应当将其放入一个池子中,可以给其他任务进行复用。

![structure-min](https://www.wailian.work/images/2018/10/18/structure-min.png)
![structure-min](https://s0.wailian.download/2018/10/18/structure-min.png)

`ThreadPoolExecutor`类提供了四个构造方法:
```
Expand Down Expand Up @@ -37,8 +37,8 @@ shutdownNow() // 也是停止接受新任务,但会中断所有的任务,将
```

### 实现原理
![process-min](https://www.wailian.work/images/2018/10/18/process-min.png)
![runState-min](https://www.wailian.work/images/2018/10/18/runState-min.jpg)
![process-min](https://s0.wailian.download/2018/10/18/process-min.png)
![runState-min](https://s0.wailian.download/2018/10/18/runState-min.jpg)

1. 线程池状态
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ AbstractQueuedSynchronizer.compareAndSetState(int, int)

节点成为sync队列和condition队列构建的基础,在同步器中就包含了sync队列。同步器拥有三个成员变量:sync队列的头结点`head`、sync队列的尾节点`tail`和状态`state`。对于锁的获取,请求形成节点,将其挂载在尾部,而锁资源的转移(释放再获取)是从头部开始向后进行。对于同步器维护的状态`state`,多个线程对其的获取将会产生一个链式的结构。

![AQS-Node-min](https://www.wailian.work/images/2018/10/25/AQS-Node-min.png)
![AQS-Node-min](https://s0.wailian.download/2018/10/25/AQS-Node-min.png)

### API说明

Expand Down Expand Up @@ -106,7 +106,7 @@ private Node enq(final Node node) {
```

### 独占模式获取
![acquire-min](https://www.wailian.work/images/2018/10/25/acquire-min.png)
![acquire-min](https://s0.wailian.download/2018/10/25/acquire-min.png)
```
public final void acquire(int arg) {
// tryAcquire 由子类实现本身不会阻塞线程,如果返回 true,则线程继续。如果返回 false 那么就加入阻塞队列阻塞线程,并等待前继节点释放锁。
Expand Down Expand Up @@ -321,7 +321,7 @@ private boolean doAcquireNanos(int arg, long nanosTimeout) throws InterruptedExc
1. 计算再次休眠的时间;
1. 休眠时间的判定。

![doAcquireNanos-min](https://www.wailian.work/images/2018/10/25/doAcquireNanos-min.png)
![doAcquireNanos-min](https://s0.wailian.download/2018/10/25/doAcquireNanos-min.png)

### `acquireInterruptibly(int arg)`
该方法提供获取状态能力,当然在无法获取状态的情况下会进入sync队列进行排队,这类似`acquire`,但是和`acquire`不同的地方在于它能够在外界对当前线程进行中断的时候提前结束获取状态的操作,换句话说,就是在类似`synchronized`获取锁时,外界能够对当前线程进行中断,并且获取锁的这个操作能够响应中断并提前返回。
Expand Down
2 changes: 1 addition & 1 deletion doc/source/jvm/jmxCollection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
>The JMX technology provides the tools for building distributed, Web-based, modular and dynamic solutions for managing and monitoring devices, applications, and service-driven networks. By design, this standard is suitable for adapting legacy systems, implementing new management and monitoring solutions, and plugging into those of the future.
## JMX架构图
![jmx-min](https://www.wailian.work/images/2019/08/19/jmx-min.png)
![jmx-min](https://s0.wailian.download/2019/08/19/jmx-min.png)

1. 基础层:主要是MBean,被管理的资源
2. 适配层:MBeanServer,主要是提供对资源的注册和管理
Expand Down
20 changes: 10 additions & 10 deletions doc/source/jvm/jvmCollection.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@
- 一个是效率问题,标记和清除过程的效率都不高;
- 另外一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

![jvm-Mark-Sweep-min](https://www.wailian.work/images/2018/11/01/jvm-Mark-Sweep-min.png)
![jvm-Mark-Sweep-min](https://s0.wailian.download/2018/11/01/jvm-Mark-Sweep-min.png)

### 复制算法
“复制”(Copying)算法,将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法的代价是将内存缩小为原来的一半,持续复制长生存期的对象则导致效率降低。

![jvm-Copying-min](https://www.wailian.work/images/2018/11/01/jvm-Copying-min.png)
![jvm-Copying-min](https://s0.wailian.download/2018/11/01/jvm-Copying-min.png)

### 标记-压缩算法
“标记-整理”(Mark-Compact)算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

![jvm-Mark-Compact-min](https://www.wailian.work/images/2018/11/01/jvm-Mark-Compact-min.png)
![jvm-Mark-Compact-min](https://s0.wailian.download/2018/11/01/jvm-Mark-Compact-min.png)

### 分代收集算法
GC分代的基本假设:绝大部分对象的生命周期都非常短暂,存活时间短。

“分代收集”(Generational Collection)算法,把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。

## 垃圾收集器
![jvm-gc-min](https://www.wailian.work/images/2018/11/01/jvm-gc-min.jpg)
![jvm-gc-min](https://s0.wailian.download/2018/11/01/jvm-gc-min.jpg)

### Serial收集器
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用**一个线程**去回收。垃圾收集的过程中会Stop The World(服务暂停)
Expand Down Expand Up @@ -77,9 +77,9 @@ CMS收集器是基于“标记-清除”算法实现的,运作过程分为4个
1. **空间整合**,G1收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。
1. **可预测停顿**,这是G1的另一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

![jvm-Concurrent-Marking-min](https://www.wailian.work/images/2018/11/01/jvm-Concurrent-Marking-min.png)
![jvm-Copy-min](https://www.wailian.work/images/2018/11/01/jvm-Copy-min.png)
![jvm-Clean-up-min](https://www.wailian.work/images/2018/11/01/jvm-Clean-up-min.png)
![jvm-Concurrent-Marking-min](https://s0.wailian.download/2018/11/01/jvm-Concurrent-Marking-min.png)
![jvm-Copy-min](https://s0.wailian.download/2018/11/01/jvm-Copy-min.png)
![jvm-Clean-up-min](https://s0.wailian.download/2018/11/01/jvm-Clean-up-min.png)

G1的新生代收集跟ParNew类似,当新生代占用达到一定比例的时候,开始出发收集。和CMS类似,G1收集器收集老年代对象会有短暂停顿。收集步骤:
1. **标记阶段**,首先初始标记(Initial-Mark),这个阶段是停顿的(Stop the World Event),并且会触发一次普通Mintor GC。对应GC log:GC pause (young) (inital-mark)
Expand All @@ -104,17 +104,17 @@ G1的新生代收集跟ParNew类似,当新生代占用达到一定比例的时
## Java内存模型
Java (JVM) Memory Model

![Java-Memory-Model-min-min](https://www.wailian.work/images/2019/04/24/Java-Memory-Model-min-min.png)
![Java-Memory-Model-min-min](https://s0.wailian.download/2019/04/24/Java-Memory-Model-min-min.png)

### Minor GC vs Major GC vs Full GC
![minor-gc-major-gc-full-gc-min](https://www.wailian.work/images/2019/04/24/minor-gc-major-gc-full-gc-min.jpg)
![minor-gc-major-gc-full-gc-min](https://s0.wailian.download/2019/04/24/minor-gc-major-gc-full-gc-min.jpg)

- every Minor GC cleans the Young generation.
- Major GC is cleaning the Tenured space.
- Full GC is cleaning the entire Heap – both Young and Tenured spaces.

## 编译过程
![jvm-compile-min-min](https://www.wailian.work/images/2019/04/24/jvm-compile-min-min.png)
![jvm-compile-min-min](https://s0.wailian.download/2019/04/24/jvm-compile-min-min.png)

## References
- [jvm系列(三):java GC算法 垃圾收集器](http://www.cnblogs.com/ityouknow/p/5614961.html)
Expand Down
8 changes: 4 additions & 4 deletions doc/source/jvm/jvmNote.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- Java发展至今,出现过很多虚拟机,最初Sun使用的一款Classic的Java虚拟机,到现在最广泛的是HotSpot虚拟机。除Sun外,还有BEA的JRockit,目前JRockit和HotSpot都被Oracle收入旗下,大有整合的趋势。

## 1.2 认识Java虚拟机的基本结构
![jvm-structure-min](https://www.wailian.work/images/2018/11/01/jvm-structure-min.png)
![jvm-structure-min](https://s0.wailian.download/2018/11/01/jvm-structure-min.png)

重点:Java堆、垃圾回收系统

Expand All @@ -28,7 +28,7 @@
- 栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。
- 方法区则是辅助堆栈的一块永久区(Perm),解决堆栈信息的产生,是先决条件。

![jvm-new-user-min](https://www.wailian.work/images/2018/11/01/jvm-new-user-min.png)
![jvm-new-user-min](https://s0.wailian.download/2018/11/01/jvm-new-user-min.png)

我们创建一个新的对象`User`,那么,`User`类的一些信息(类信息、静态信息都存放在方法区中)
-`User`类被实例化出来之后,被存储到Java堆中,一块内存空间
Expand All @@ -37,7 +37,7 @@
## 2.2 辨清Java堆
Java堆是和Java应用程序关系最密切的内存空间,几乎所有的对象都会存放在其中,并且Java堆完全是自动化管理的,通过垃圾回收机制,垃圾对象会自动清理,不需要显示地释放。

![jvm-memory-model-min](https://www.wailian.work/images/2018/11/01/jvm-memory-model-min.png)
![jvm-memory-model-min](https://s0.wailian.download/2018/11/01/jvm-memory-model-min.png)

根据垃圾回收机制不同,Java堆可能拥有不同的结构。最为常见的就是将整个Java堆分为新生代和老年代。其中新生代存放新生的对象或者年龄不大的对象,老年代则存放年老对象。
- 新生代分为eden区、s0区、s1区,s0和s1也被成为from和to区域,它们是两块大小相等,并且可以互换角色的空间。
Expand Down Expand Up @@ -153,7 +153,7 @@ TLAB全称是Thread Local Allocation Buffer即线程本地分配缓存,从名
## 4.6 对象创建流程
一个对象创建在什么位置,JVM会有一个比较细节的流程,根据数据的大小,参数的设置,决定如何创建分配,以及其位置。

![jvm-create-obj-min](https://www.wailian.work/images/2018/11/04/jvm-create-obj-min.png)
![jvm-create-obj-min](https://s0.wailian.download/2018/11/04/jvm-create-obj-min.png)

## 5.x 垃圾收集器

Expand Down
2 changes: 1 addition & 1 deletion doc/source/jvm/understand-jvm/UnderstandingTheJvm02.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 深入理解Java虚拟机 Chapter02

### 运行时数据区域
![jvm-structure-min](https://www.wailian.work/images/2018/11/01/jvm-structure-min.png)
![jvm-structure-min](https://s0.wailian.download/2018/11/01/jvm-structure-min.png)
2 changes: 1 addition & 1 deletion doc/source/jvm/understand-jvm/UnderstandingTheJvm03.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## 深入理解Java虚拟机 Chapter03

### 垃圾收集器
![jvm-gc-min](https://www.wailian.work/images/2018/11/01/jvm-gc-min.jpg)
![jvm-gc-min](https://s0.wailian.download/2018/11/01/jvm-gc-min.jpg)

### 垃圾收集器参数总结

Expand Down

0 comments on commit 2e92591

Please sign in to comment.