Skip to content

Commit

Permalink
update toc format
Browse files Browse the repository at this point in the history
  • Loading branch information
rbmonster committed Apr 19, 2022
1 parent cda8452 commit 0667ba8
Show file tree
Hide file tree
Showing 6 changed files with 453 additions and 205 deletions.
54 changes: 52 additions & 2 deletions src/main/java/com/learning/basic/JVM.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ staticObj随着Test的信息类型存放在方法区,instantObj随着Test对
弱分代假说:绝大多数对象都是朝生夕灭。\
强分代假说:熬过越多次垃圾收集过程的对象就越难消亡。\
跨代引用假说:存在于新生代的对象可能会引用老年代的对象。因此该假说说明的是,存在互相引用关系的对象,是应该倾向于同时生存或者同时死亡。
- 解决方案,在新生代上建立一个全局的数据结构(记忆集),这个结构把老年代划分成若干小块,表示出老年代的哪一块内存会存在跨代引用。之后发生Minor GC时,只有包含跨代引用的小块内存才会加入到GC Root的扫描.
> 解决方案,在新生代上建立一个全局的数据结构(记忆集),这个结构把老年代划分成若干小块,表示出老年代的哪一块内存会存在跨代引用。之后发生Minor GC时,只有包含跨代引用的小块内存才会加入到GC Root的扫描.

#### 标记-清除算法
Expand All @@ -312,8 +312,58 @@ staticObj随着Test的信息类型存放在方法区,instantObj随着Test对
移动对象的优缺点:
- 缺点:在老年代这种每次回收都有大量存活的区域,移动存活对象并更新所有引用这些对象的地方会是一种极其负重的工作,工作期间必须暂停用户应用程序才能进行。
- 优点:内存规整,解决了空间碎片化问题。空间碎片化问题只能依赖更复杂的内存分配器和内存访问器来解决。
- 综合的解决方案,平常都是用标记-清除算法,直到空间碎片化已经影响到对象分配,再使用标记-整理算法。
综合的解决方案,平常都是用标记-清除算法,直到空间碎片化已经影响到对象分配,再使用标记-整理算法。

#### 三色标记算法
三色标记算法:GCRoot如果想查找到存活对象,会根据可达分析算法分析,遍历整个引用链 ,按照是否访问过该对象分成三种不同的颜色盒子(容器):白色、灰色、黑色盒子。

> 白色:本对象没有被访问过 (没有被GCRoot扫描过,有可能是为垃圾对象);\
灰色:本对象已经被访问过(被GCRoot扫描过),且本对象中的属性没有被GCRoot扫描,该对象就是为灰色对象;如果该对象的属性被扫描的情况下,从灰色变为黑色。\
黑色:本对象已经被访问过(被GCRoot扫描过),且本对象中的属性已经被GCRoot扫描过,该对象就是为黑色对象。

![avatar](https://github.com/rbmonster/file-storage/blob/main/learning-note/learning/basic/color-mark.png)

>三色标记算法缺陷:在并发标记阶段的时候,因为用户线程与GC线程同时运行,有可能会产生多标或者漏标;\
多标--多标记(浮动垃圾)\
漏标--漏标记

**浮动垃圾**
1. 并发标记:用户与GC线程同时运行,假设现在扫描到C对象,B对象变为黑色,用户线程执行C的属性E=null,GC线程扫描C对象引用链,认为E对象是为可达对象,但是C对象根本没有引入到E对象,E对象应该是为垃圾对象,这种问题,可以在重新标记阶段(修正)修复。
2. 并发清除阶段:用户与GC线程同时运行,会产生新的对象但是没有及时被GC清理。 只能在下一次GC清理垃圾的修复。

**漏标问题**

![avatar](https://github.com/rbmonster/file-storage/blob/main/learning-note/learning/basic/mark-problem.png)
1. 用户线程先执行C的E属性=null;GC线程的GcRoot就扫描不到E。GC就认为E对象就是为垃圾对象,不可达对象。
2. 用户线程执行B.E属性=E;E对象就是应该是为可达对象。
因为GCRoot是从C开始,不会从黑色的B开始,就会导致漏标的情况发生。

漏标的问题产生满足两个条件:
1. 至少有一个黑色对象指向了白色对象
2. 在所有灰色对象扫描完整个链时,删除之前所有白色对象引用关系。


CMS如何解决漏标问题---写屏障+增量更新方式
> 满足一个条件(灰色对象与白色对象断开连接),在并发标记阶段当我们黑色对象(B)引用关联白色对象(E),记录下B黑色对象。\
在重新标记阶段(所有用户线程暂停),有将B对象变为灰色对象将整个引用链全部扫描。\
缺点:遍历B整个链的效率非常低,有可能会导致用户线程等待的时间非常长。

G1如何解决漏标问题---原始快照方式
> 在C(灰色对象)断开E(白色)的时候,会记录原始快照,在重新标记阶段的时候以白色对象变为灰色为起始点扫描整个链,本次GC是不会被清理。\
好处:如果假设B(黑色对象)引入该白色对象的时候,无需做任何遍历效率是非常高。\
缺点:如果假设B(黑色对象) 没有引入该白色对象的时候,该白色对象在本次GC继续存活,只能放在下一次GC在做并发标记的时候清理。\
**tips:以浮动垃圾(占内存空间)换让我们用户线程能够暂停的时间更加短。**

总结:
CMS收集器解决漏标问题:增量方式 如果现在B(黑色)对象引入白色对象,写屏障。
- 好处:避免浮动垃圾
- 缺点扫描整个引用链效率比较低。

G1收集器解决漏标问题:原始快照方式。
- 好处:效率非常高,无需扫描整个引用链
- 缺点:可能会产生浮动垃圾。

参考资料:[CMS和G1的漏标问题解决及三色标记算法图解](https://www.jianshu.com/p/bbc10c98d0d6)

### 新生代垃圾回收
1. eden、 survivor From 复制到 survivor To,年龄+1。
Expand Down
88 changes: 55 additions & 33 deletions src/main/java/com/toc/ALGORITHM.md
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ void slidingWindow(string s, string t) {
1. 第一种为size是题目要求的,如k长的窗口最大值
2. 第二种为size是当前满足的最优接。left位置不匹配,则平滑窗口。result即为`right-left`

- [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/)
- [替换后的最长重复字符](https://leetcode-cn.com/problems/longest-repeating-character-replacement/)
- [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/)

Expand Down Expand Up @@ -1052,7 +1053,7 @@ public class Solution {

### <a name="36">单调队列</a><a style="float:right;text-decoration:none;" href="#index">[Top]</a>

单调队列,即单调递减或单调递增的队列。
单调队列,即单调递减或单调递增的队列。\
需要使用 双向队列 ,假设队列已经有若干元素:
- 当执行入队 push_back() 时: 若入队一个比队列某些元素更大的数字 xx ,则为了保持此列表递减,需要将双向队列 尾部所有小于 xx 的元素 弹出。
- 当执行出队 pop_front() 时: 若出队的元素是最大元素,则 双向队列 需要同时 将首元素出队 ,以保持队列和双向队列的元素一致性。
Expand Down Expand Up @@ -1090,16 +1091,17 @@ class MaxQueue {
```
- [剑指 Offer 59 - II. 队列的最大值](https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/)
- [剑指 Offer 59 - I. 滑动窗口的最大值](https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/): review
- [环形子数组的最大和](https://leetcode-cn.com/problems/maximum-sum-circular-subarray/)
- [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/)
- [绝对差不超过限制的最长连续子数组](https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/)
- [跳跃游戏 VI](https://leetcode-cn.com/problems/jump-game-vi/)

## <a name="37">栈</a><a style="float:right;text-decoration:none;" href="#index">[Top]</a>
- 栈具有记忆的功能,由其数据的特殊性可以用来DFS搜索
栈具有记忆的功能,由其数据的特殊性可以用来DFS搜索

- [回文链表](https://leetcode-cn.com/problems/palindrome-linked-list/)
- [有效的括号](https://leetcode-cn.com/problems/valid-parentheses/ )
- *[最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/)
- *[字符串解码](https://leetcode-cn.com/problems/decode-string/)
- [最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/): review
- [字符串解码](https://leetcode-cn.com/problems/decode-string/): review
- [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/)
- [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/)

Expand Down Expand Up @@ -1173,42 +1175,62 @@ public class Solution {


### <a name="39">单调栈</a><a style="float:right;text-decoration:none;" href="#index">[Top]</a>
单调栈: 单调栈实际上就是栈, 只是利⽤了⼀些巧妙的逻辑, 使得每次新元素⼊栈后, 栈内的元素都保持有序(单调递增或单调递减) 。
单调栈:单调栈实际上就是栈,只是利⽤了⼀些巧妙的逻辑,使得每次新元素⼊栈后,栈内的元素都保持有序(单调递增或单调递减)。
> 单调栈相关问题tag,_获取下一个__求最近最大或最小的值_、下标
```java
class Solution {
public int[] dailyTemperatures(int[] T) {
Deque<Integer> stack = new LinkedList<>();
int len = T.length;
int[] res = new int[len];
// 从尾到头遍历
for (int i = len - 1; i >= 0; i--) {
while (!stack.isEmpty() && T[stack.peek()] <= T[i]) {
stack.pop();
}
// 判断位置差值
res[i] = stack.isEmpty() ? 0 : stack.peek() - i;
stack.push(i);
public int[] template(int[] T) {
// 单调递增栈
Deque<Integer> minStack = new LinkedList<>();
int len = T.length;
int[] res = new int[len];
// 从头到尾遍历或从尾到头遍历
for (int i = len - 1; i >= 0; i--) {
while (!minStack.isEmpty() && T[minStack.peek()] <= T[i]) {
// 判断是否对pop元素进行处理
// i为 pop元素 最近小于i的位置
minStack.pop();
}
// 当前stack.peek()元素为小于i对最近的位置,是否进行处理
minStack.push(i);
}
return res;
}

public int[] template2(int[] T) {
// 单调递增栈
Deque<Integer> maxStack = new LinkedList<>();
int len = T.length;
int[] res = new int[len];
// 从头到尾遍历或从尾到头遍历
for (int i = len - 1; i >= 0; i--) {
while (!maxStack.isEmpty() && T[maxStack.peek()] >= T[i]) {
// 判断是否对pop元素进行处理
// i为 pop元素 最近大于的位置
maxStack.pop();
}
// 当前stack.peek()元素为 大于i对最近的位置,是否进行处理
maxStack.push(i);
}
return res;
}
return res;
}
}
```

- [最小栈](https://leetcode-cn.com/problems/min-stack/)
- [每日温度](https://leetcode-cn.com/problems/daily-temperatures/)
- [下一个更大元素 I](https://leetcode-cn.com/problems/next-greater-element-i/)
- [最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/)
> 单调栈类似思想

- *[接雨水](https://leetcode-cn.com/problems/trapping-rain-water/)
> 单调栈解法,递减栈,每次计算增量
- *[柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/)
- [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/)
> 最大矩形计算,获取索引i的左右小于`height[i]`的最高点索引

- [下一个更大元素 I](https://leetcode-cn.com/problems/next-greater-element-i/): hash与单调栈结合
- [下一个更大元素 II](https://leetcode-cn.com/problems/next-greater-element-ii/)
- [最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/): 单调栈类似思想
- [去除重复字母](https://leetcode-cn.com/problems/remove-duplicate-letters/)
- [移掉 K 位数字](https://leetcode-cn.com/problems/remove-k-digits/)

以下三个为类似问题:
- [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/): 单调栈解法,递减栈,每次计算增量
- [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/): review
- [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/): **理解为主**,如何转化问题,变成最大矩形计算。获取索引i的左右小于`height[i]`的最高点索引

- [最多能完成排序的块](https://leetcode-cn.com/problems/max-chunks-to-make-sorted/): 单调栈的变形

## <a name="40">BFS 与 DFS</a><a style="float:right;text-decoration:none;" href="#index">[Top]</a>
BFS与DFS相关的问题,经常都可以用两种方式求解,因此把相关问题放一起。
Expand Down
Loading

0 comments on commit 0667ba8

Please sign in to comment.