Skip to content

Commit

Permalink
Update Blog content
Browse files Browse the repository at this point in the history
  • Loading branch information
JSD-qr committed Dec 12, 2023
1 parent 1529506 commit ffbb40c
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 6 deletions.
Binary file added src/.vuepress/public/ico/Z-Library.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/.vuepress/public/ico/gc-easy.ico
Binary file not shown.
62 changes: 57 additions & 5 deletions src/note/java/jvm/2311071055.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ enum {

这是因为JVM启动时会进行一系列复杂活动,比如类装载配置,系统类初始化等。在这个过程中会使用大量synchronized关键字为对象加锁,且这些锁大多数都不是偏向锁。为了减少初始化时间,JVM默认延迟加载偏向锁。

#### 匿名偏向

当JVM启用了偏行锁模式(JDK6后默认启用),新创建对象的对行头重ThreadId为0,说明此时处于可偏向但是未偏向任何线程,
也叫做 **匿名偏向** 状态(anonymously biased)。

例子:

```java
Expand Down Expand Up @@ -214,11 +219,6 @@ Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
```

#### 匿名偏向

当JVM启用了偏行锁模式(JDK6后默认启用),新创建对象的对行头重ThreadId为0,说明此时处于可偏向但是未偏向任何线程,
也叫做 **匿名偏向** 状态(anonymously biased)。

#### 偏向锁撤销-调用HashCode

调用锁对象的hashCode()或者System.identityHashCode(obj)方法会导致该对象的偏向锁被撤销。
Expand All @@ -239,6 +239,58 @@ Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

轻量级锁适合的场景是线程交替执行同步块的场合,如果存在同一时间多个线程同时访问一把锁的场景时,轻量级锁就会膨胀升级为重量级锁。

#### 轻量锁是否存在自旋

轻量锁加锁失败会自旋,失败一定次数后会膨胀为重量锁这种理解是**错误**的!

轻量锁不存在自旋,只有重量锁加锁事变才会自旋。重量锁加锁失败,会多次尝试cas和自适应自旋,如果一直加锁失败就会阻塞当前线程,等待唤醒。

之所以这么设计,是因为轻量级锁本身就不是为了处理过于激烈的竞争场景,而是为了应对线程之间交替获取锁的场景。

### 重量锁

### 锁升级流程

![锁实现原理](https://qiniu.yanggl.cn/image/202311101455325.png)

## 锁优化进阶

### 批量重偏向&批量撤销

通过偏向锁加解锁过程,当只有一个线程反复进入同步块,偏向锁带来的性能开销基本可以忽略,但是当有其他线程尝试获取锁时,就需要等到safePoint时,再将偏向锁撤销为无锁或升级为轻量锁,这会消耗一定的性能。
所以,当处于多线竞争频繁的情况下,偏向锁不仅不能提高性能,还会导致性能下降。

#### 批量重偏向

#### 批量重撤销

### 自旋优化

重量级在竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(持有锁的线程已经释放锁了),当前线程就可以直接去获取锁避免阻塞。需要注意的是自旋会占用cpu时间,多核cpu自旋才能发挥优势。

在JDK6之后自旋是自适应的,比如对象刚刚的一次自旋操作成功过,那么认为这次自旋成功的可能性会很高,就会多自旋几次,否则就少自旋甚至不自旋,较为智能。

> 自旋的目的是为了减少线程挂机的次数,尽量避免直接挂机线程,因为挂记操作设计系统调用,存在用户态和内核态切换,这部分的开销是很大的
### 锁粗化

锁粗化是为了处理当有一系列连续的操作都会对同一个对象反复加/解锁,甚至连续加锁的操作都是在同一个方法体的情况。
这样的操作即使没有出现线程竞争,频繁地进行同步操作也会导致不必要地性能损耗。

如果JVM检测到有一连串地操作都是对同一对象加锁,将会扩大锁地范围(锁粗化)到整个一连串操作地外部

```java
StringBuffer buffer = new StringBuffer();

public void append() {
buffer.append("a").append("b").append("c");
}
```

> 上述为一个锁粗化的简单案例,当JVM检测到之后,会将其合并称一次范围更大的加/解锁操作,既在第一次append时加锁,在最后一次append结束后解锁。
### 锁消除

锁消除就是删掉一些不必要的加锁操作。

锁消除的操作是在编译期间,对运行上下文扫描,去除不可能存在临界资源竞争的锁(锁消除),以节省毫无意义的请求锁的时间。
31 changes: 31 additions & 0 deletions src/note/java/jvm/2311221518.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
isOriginal: true
order: 6
date: 2023-11-22
index: true
category:

- Java

tag:

- JVM

---

# JIT(即时编译)深入理解

## 热点探测技术

## 方法内联

## 锁消除

## 锁粗化

## 逃逸分析技术

## 标量替换

## 栈上分配

24 changes: 23 additions & 1 deletion src/resources/navigation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ link: https://note.youdao.com/
color: rgba(253, 230, 135, 0.15)
```

```card
title: GCeasy
desc: 业内首款借助机器学习技术引导的垃圾回收日志分析工具。GCeasy 内置有智能功能,可自动检测 JVM 和 Android GC 日志中的问题并推荐解决方案。
logo: /ico/gc-easy.ico
link: https://gceasy.ycrash.cn/
color: rgba(253, 230, 135, 0.15)
```

:::

## 语言大模型
Expand All @@ -87,7 +95,7 @@ color: rgba(253, 230, 135, 0.15)
title: 文心一言
desc: 百度全新一代知识增强大语言模型,文心大模型家族的新成员
logo: /ico/wenxin.png
link: https://note.youdao.com/
link: https://yiyan.baidu.com/
color: rgba(253, 230, 135, 0.15)
```

Expand All @@ -100,3 +108,17 @@ color: rgba(253, 230, 135, 0.15)
```

:::

## 学习

::: card

```card
title: Z-Library
desc: 好用、免费的电子书获取网站
logo: /ico/Z-Library.png
link: https://zh.zlibrary-east.se/
color: rgba(253, 230, 135, 0.15)
```

:::

0 comments on commit ffbb40c

Please sign in to comment.