VirtualThread Pin的处理总结

简介: VirtualThread Pin的处理总结

Pin的状态指的是VirtualThread在freeze时无法让出Carrier Thread(协程执行时挂载的物理线程)。主要有两种情况下会导致Pin:

VirtualThread的调用栈包含JNI frame。因为JNI调用的实现是C++代码,可以做的事情非常多,例如它可以保存当前Carrier Thread的Thread ID,如果这时切换出去,那么下一次执行时,如果另一个Carrier Thread来执行这个协程,将会产生逻辑错误(Carrier Thread的ID不一致);

VirtualThread持有synchronized锁。这是java早期锁的实现带来的限制,因为java的synchronized锁的owner是当前的Carrier Thread,如果一个协程持有一把锁,但是锁的owner被认为是当前的Carrier Thread,那么如果接下来这个Carrier Thread又去执行另一个协程,可能另一个协程也被认为拥有了锁,这可能导致同步的语义发生混乱,产生各种错误。

偶尔出现的Pin并不是一个很严重的问题,只要调度器中始终有物理线程负责执行协程就可以。如果调度器中所有的物理线程都被Pin住,可能会对吞吐量产生较大影响。Loom针对默认的调度器ForkJoinPool做了优化,如果发现所有的物理线程都被Pin住,就会额外创建一些物理线程,保证协程的执行不受太大影响。用户如果想要彻底消除Pin,可以按照如图3.4的方式,通过-Djdk.tracePinnedThreads选项定位产生Pin的调用栈。

3. 协程性能优化:Pin的解决。3.3小节介绍过Pin,Pin虽然不会导致整个系统死锁,但是频繁的Pin仍然会显著降低业务的吞吐量。对于Pin的解决,主要是两个方面,即产生Pin的两个原因:synchronized锁和native frame。第一步,在调试阶段开启-Djdk.tracePinnedThreads,这样可以找到所有引起Pin的调用栈。如果Pin是由于业务代码使用synchronized锁引起的,那么只需要将synchronized锁替换成ReentrantLock即可;如果Pin是由于包含native frame或者第三方代码包含synchronized锁引起的,那么只能通过将任务提交到一个独立线程池的方法来解决,这样可以保证协程的执行不受影响。

Detecting pinning

The current prototype has rudimentary support for reporting when a thread is pinned, say when a virtual thread parks while owning a monitor or with a native frame on the stack. This reporting is enabled by running with the system property jdk.tracePinnedThreads specified to the java launcher.

Running with -Djdk.tracePinnedThreads (or -Djdk.tracePinnedThreads=full) will print a complete stack trace of a virtual thread when parking pins its carrier thread. The reason, be it native frames, synchronized frames, or frames with synchronized blocks will be highlighted in the output.

Running with -Djdk.tracePinnedThreads=short will print a “short” stack trace that includes just the frames with problematic code.

The reporting is filtered to avoid the printing the same stack trace repeatedly.

-Djdk.tracePinnedThreads=full
目录
相关文章
|
7月前
|
存储 调度 数据库
STM32--DMA
STM32--DMA
|
7月前
|
C语言 芯片
LED 底层原理 和 GPIO引脚、寄存器操作
LED 底层原理 和 GPIO引脚、寄存器操作
LED 底层原理 和 GPIO引脚、寄存器操作
|
7月前
|
传感器 数据采集 存储
STM32--GPIO
STM32--GPIO
|
API SoC
pinctrl和gpio子系统
pinctrl和gpio子系统
124 0
|
存储 芯片 内存技术
浅析DMA
DMA全程Direct Memory Access,即直接存储器访问。简单来讲,它的功能是把数据从一个地址搬运到另一个地址。通常有三个传输方向,分别是内存到内存,内存到外设和外设到内存。DMA是开发过程中常用到的,但从个人角度来讲,觉得DMA不是很好学。倒不是说他有多难,只是有些寄存器位的含义可能初学时了解的不深刻,很容易出现问题,这里仅代表个人看法。有的DMA也有一些特殊的传输方式,比如回绕传输,这个在第3小节会有详细介绍。
379 0
|
存储
STM32F103C8 GPIO
STM32F103C8 GPIO
177 0
|
Linux 芯片
GPIO和Pinctrl子系统的使用
GPIO和Pinctrl子系统的使用
100 0
|
缓存 开发工具 芯片
ZYNQ-AXI GPIO使用(一)
ZYNQ-AXI GPIO使用
1231 1
ZYNQ-AXI GPIO使用(一)
|
编译器
STM32的HAL库开发系列 - GPIO中断/外部中断EXTI
STM32的HAL库开发系列 - GPIO中断/外部中断EXTI
694 0
|
智能硬件
GPIO中断/外部中断EXTI的初始化
GPIO中断/外部中断EXTI的初始化
382 0