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
目录
相关文章
|
存储 Oracle Java
分代 ZGC 详解
本文主要介绍JDK21中的分代ZGC详解,包括染色指针、内存屏障等核心概念及ZGC JVM参数介绍 ZGC(Z Garbage Collector)是Java平台上的一种垃圾收集器,它是由Oracle开发的,旨在解决大堆的低延迟垃圾收集问题。ZGC是一种并发的分代垃圾收集器,它主要针对具有大内存需求和低停顿时间要求的应用程序。
分代 ZGC 详解
|
Dubbo Java 测试技术
分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比较
Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。不过,略有遗憾的是,据说在淘宝内部,dubbo由于跟淘宝另一个类似的框架HSF(非开源)有竞争关系,导致dubbo团队已经解散(参见http://www.oschina.net/news/55059/druid-1-0-9 中的评论),反到是当当网的扩展版本仍在持续发展,墙内开花墙外香。
8000 0
|
前端开发 Java 应用服务中间件
Gateway网关使用不规范,同事加班泪两行~
Gateway网关使用不规范,同事加班泪两行~
Gateway网关使用不规范,同事加班泪两行~
|
存储 网络协议 Java
【JDK21】详解虚拟线程
【JDK21】详解虚拟线程
785 0
|
安全 Oracle Java
JDK 21预告:虚拟线程正式发布及十多项新特性
JDK 21预告:虚拟线程正式发布及十多项新特性
385 0
|
算法 安全 物联网
关于SM2、SM3、SM4、SM9这四种国密算法
本文介绍了四种国密算法——SM2、SM3、SM4和SM9。SM2是一种基于椭圆曲线的非对称加密算法,用于数据加密和数字签名;SM3是哈希算法,用于数字签名和消息完整性验证;SM4是对称加密算法,用于数据加密和解密;SM9是基于标识的非对称密码算法,适用于物联网环境中的数据安全和隐私保护。
8688 0
|
测试技术 开发者
单元测试问题之在Mockito中静态方法的调用,如何模拟
单元测试问题之在Mockito中静态方法的调用,如何模拟
|
消息中间件 JSON Java
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
27485 0
|
算法 Oracle Java
一文详解|从JDK8飞升到JDK17,再到未来的JDK21
本文深入浅出地解析了从JDK8到JDK17版本升级的新特性,并展望后续将会更新的JDK21.
11535 8
|
运维 监控 算法
JDK 21中的分代ZGC:内存管理的革命性进步
本文深入探讨了JDK 21中引入的分代ZGC(Z Garbage Collector)的工作原理、特性及其对现代应用程序性能的影响。分代ZGC是一种基于分代收集的垃圾回收器,通过优化内存分配和回收过程,实现了更高的吞吐量和更低的延迟。本文将分析分代ZGC的设计哲学、技术细节以及在实际应用中的优势,并展示如何通过配置和优化分代ZGC来提升Java应用程序的性能。
1480 7

热门文章

最新文章