【译】虚拟线程:绝对优势

news2024/11/28 21:38:18

原文地址:Virtual Threads: A Definite Advantage

一、前言

深入了解虚拟线程如何提高应用程序的性能和可扩展性,同时将线程管理开销降到最低。

探索虚拟线程是一件很棒的事情,它是 Java 的一项强大功能,有望彻底改变多线程应用程序。在本文中,我们将深入探讨虚拟线程如何提高应用程序的性能和可扩展性,同时将线程管理的开销降到最低。让我们开始这段旅程,充分发挥虚拟线程的潜力!

在这里插入图片描述

为了证明这个用例,我们将创建一百万个平台线程和虚拟线程。生成这些线程后,我们将使用 HeapHero 和 fastThread 工具分析它们的堆和线程行为。通过这种探索,我们旨在突出平台线程和虚拟线程在性能上的区别。

二、什么是 Java 中的虚拟线程(VT)?

虚拟线程是一种不与特定操作系统线程绑定的线程创建方式。这对需要创建大量线程的应用程序非常有用,因为它可以减少创建和管理每个线程的开销。对于需要创建非临时线程的应用程序来说,它们也很有用,因为它们可以保证每个线程都有机会运行。

Java 21 引入了这一功能。虚拟线程也被称为 “绿色线程” 或 “轻量级线程”。它是线程的一种软件实现,使用操作系统的线程来实现并发。它们由 Java 虚拟机(JVM)管理,程序员无感知。

三、为什么虚拟线程很特别?

虚拟线程是一种特殊类型的线程,由平台线程创建,创建时只占用极少量的资源。由于具有这种功能,因此可以生成许多虚拟线程,用于多线程编程。

由于创建虚拟线程的成本很低,它不会像平台线程那样产生任何错误。虚拟线程的另一个优点是不需要像 Java 中的平台线程那样将它们池化。

四、平台线程(Platform Threads)

平台线程是 JDK 中的本地线程(java.lang.Thread)。

我们将使用 Java 中的线程类生成一百万个线程。在创建这些庞大线程的过程中,操作系统会变得极不稳定,并抛出 OutOfMemoryError。我们将在 Ubuntu Linux 中对这种行为进行实验。本实验使用的 JDK 版本为 21。

static int cnt = 1; 
public static void main(String[] args) { 
    for(int i = 0; i < 1000000; i++) {
        new Thread(
              new Runnable() {
                  @Override
                  public void run() {                         
                      try {                             
                          TimeUnit.HOURS.sleep(1);                         
                      } catch (Exception ex) {}
                  }
             }
         ).start();
        cnt++;
   }
}

在上面的代码中,我们在 for 循环中创建了一百万个线程,每个线程的休眠期最长可达 1 小时。线程休眠时,操作系统会缓存所有资源。在这种特殊情况下,操作系统需要将每个线程的所有资源保存较长时间,这是一项非常耗费资源的操作。请记住:在 Java 中创建线程是一项非常昂贵的操作。这就是在多线程编程模式下,应用程序启动时需要池化线程的原因。

很快,上述代码就会出现 OutOfMemory 错误。您可以在下图中看到该错误:

平台线程 OutOfMemoryError

五、虚拟线程(Virtual Threads)

现在,让我们来开发虚拟线程的代码。用例相同,但我们要在一个循环中动态生成一百万个虚拟线程。

static int cnt = 1; 
public static void main(String[] args) {   
      var executor = Executors.newVirtualThreadPerTaskExecutor();   
      IntStream.range(1, 1000000).forEach(i ->{       
        Future result =  executor.submit(() ->{           
          try {               
              TimeUnit.HOURS.sleep(1);           
          } catch (InterruptedException e) {               
             throw new RuntimeException(e);           
          }           
          String uuid = UUID.randomUUID().toString();       
       });       
       if(cnt == 999999) {           
             generateHeapDump(2);       
       }       
       cnt++;   
   }); 
}

在上面的代码中,通过调用 java.util.concurrent 包中 ExecutorService 类的 newVirtualThreadPerTaskExecutor() 方法,我们动态创建了一百万个虚拟线程。

在代码执行过程中,我们将使用 generateHeapDump() 方法获取堆内存快照。我们会在计数器达到 999999 时进行堆转储。这样,我们就能确保在堆内存日志中捕获最多的数据。

六、100万个虚拟线程居然没有OOM错误!

什么是 OutOfMemoryError?当应用程序没有足够的内存来处理事务时,系统就会抛出这个错误。那么,为什么在平台线程中会出现 OutOfMemoryError 而在虚拟线程中不会呢?

我们将借助下图进一步了解:

JVM 内存快照

内存有三个部分:堆(Heap)、元空间(Metaspace)和其他(Others)。就平台线程而言,线程栈存储在其他区域。

每个线程都有独立的内存,并存储在其他区域。为线程分配内存后,在进程结束后,应释放该内存。在平台线程方案中,线程等待时间为一小时,与之相关的内存不会很快释放。而且,新线程会再次生成,它们也要等待一小时。这样,就需要在 Others 区域分配大量内存,而 JVM 无法快速释放内存。因此,它就会抛出这个错误。

平台线程容易出现 OOM 错误的另外一个原因是,JDK5.0之后,默认线程栈内存是1M,这个内存分配量远超过虚拟线程方案中把虚拟线程当成对象来管理的方式。

在虚拟线程的情况下,虚拟线程被存储在堆区域,该区域由 JVM 进程控制,因为它们被视为对象。当你运行虚拟线程场景的代码时,你可以看到它会创建一百万个虚拟线程并休眠一小时。这些虚拟线程保存在堆内存中,生成线程所需的资源非常少。因此,在这种情况下不会抛出 OutOfMemoryError。

注意:有时,在虚拟线程的情况下,它也会抛出 OutOfMemoryError。这是因为当创建大量虚拟线程时,"堆内存"将被耗尽。但在上述情况下,它不会抛出 OOM 错误,因为默认内存足以容纳 100 万个虚拟线程!

我们将通过分析平台线程和虚拟线程的线程和内存行为来证实上述理论。

七、平台线程性能比较

我们将使用 fastThread 和 HeapHero 工具集,分别进行线程和堆转储分析,对平台线程性能进行比较研究。

7.1. 线程转储分析(Thread Dump Analysis)

这是 fastthread.io 为平台线程生成的线程转储报告。该报告非常智能,可提供发生 OutOfMemoryError 的可能性。

平台线程的线程转储报告

它显示 JVM 中有近 1600 个线程,这些数字令人震惊。报告的第一部分为我们提供了有关应用程序状态的足够信息。

现在,让我们用相同的堆栈跟踪快速检查线程。下图就是相关示意图。

堆栈跟踪相同的线程

该图显示了具有相同堆栈跟踪的多个线程。这些线程处于等待阶段。这是因为应用程序创建了大量线程,并要求这些线程等待一小时(平台线程代码请参考 Thread.sleep(…))。大约有 1600 个线程被要求等待。因此,报告显示的堆栈跟踪具有相同的行为。

不过,值得注意的是报告的其余部分。可以查看详细报告,以便您更好地查看和理解。

7.2. 堆转储分析

下面是使用 heaphero.io 对同一平台线程进行的堆转储分析。

堆转储分析的堆大小

可以看到,这里的堆大小要小得多。因此我们可以说,在平台线程的情况下,如果这些数字非常高,这很可能会给应用程序带来问题。可以查看 HeapHero 工具集对平台线程进行的故障排除报告。

八、虚拟线程性能比较

我们将使用 fastThread 和 HeapHero 工具集,分别进行线程和堆转储分析,对虚拟线程的性能进行比较研究。

8.1. 线程转储分析

下面是虚拟线程的线程转储分析。可以看到,线程数量约为 37 个。为什么会出现这种情况?为什么报告中没有显示所有这一百万个线程?

虚拟线程的线程转储分析

这是因为虚拟线程不被视为线程,所以在进行线程转储时,报告中不包括虚拟线程。这份线程转储情报报告会告诉你,堆的大小会增加。

8.2. 堆转储分析

现在,让我们使用 HeapHero 网站分析虚拟线程的报告。生成的报告可能有点笨重,您需要等待一段时间才能看到详细报告。

虚拟线程的堆转储分析

首先,请看一下报告,并在其中花点时间。报告显示有 999999 个 java.lang.VirtualThreads 实例。所有这些线程都从一个 jdk.internal.misc.CarrierThread 实例引用。

虚拟线程的堆报告

这份报告的有趣之处在于堆的大小为 401 MB。在执行与虚拟线程相关的代码时,JVM 会将这一百万个虚拟线程的所有信息保存到堆区。因此,在这种情况下,堆的大小非常大。这就是问题的关键所在。这些数据肯定也符合垃圾回收的条件。下面是堆分析报告,重点说明了这一点。

九、平台与虚拟线程性能比较

现在,让我们根据下表比较线程数与堆大小:

线程数堆大小线程分析报告堆内存分析报告
平台线程测试1599个之后报OutOfMemoryError1.85 MBPlatform Thread – Thread analysis reportPlatform Thread – Heap analysis report
虚拟线程测试100万个,没有问题401 MBVirtual Thread – Thread analysis reportVirtual Thread – Heap analysis report

当平台线程代码运行时,在抛出 OutOfMemoryError 之前会产生近 1600 个线程。但在这种情况下,堆的大小相对较小。这是因为,正如本文前文所述,线程栈保存在 Others 区域内,而不是堆内。

在虚拟线程的情况下,应用程序创建的线程数量相对较少,但堆的大小却非常大。这是因为虚拟线程使用了堆内存。

十、结论

虚拟线程是创建多线程应用程序的有用工具。通过使用多个线程并行执行任务,虚拟线程可以提高应用程序的性能。虚拟线程的使用方法与多线程应用程序中使用平台线程的方法相同。在创建和管理每个线程时没有任何开销,但仍能产生更好的效果。这是 Java 语言的一项强大功能,有了这项功能,应用程序的扩展就变得非常容易。这是使用虚拟线程的一个明显优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1291184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】—红黑树(C++实现)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 &#x1f49c;本文前置知识&#xff1a; AVL树 ♈️今日夜电波&#xff1a;Letter Song—ヲタみん 1:36━━━━━━️&#x1f49f;──────── 5:35 …

编织魔法世界——计算机科学的奇幻之旅

文章目录 每日一句正能量前言为什么当初选择计算机行业计算机对自己人生道路的影响后记 每日一句正能量 人生就像赛跑&#xff0c;不在乎你是否第一个到达尽头&#xff0c;而在乎你有没有跑完全程。 前言 计算机是一个神奇的领域&#xff0c;它可以让人们创造出炫酷的虚拟世界…

上位机与PLC:ModbusTCP通讯之数据类型转换

前请提要: 从PLC读取的数值,不管是读正负整数还是正负浮点数,读取过来后都会变成UInt16,也就是Ushort类型 一、ushort(UInt16)转成 Int32 源代码方法: //ushort类型转Int32类型的方法private int ushortToInt32(ushort[] date, int start){//先进行判断,长度是否正确…

在线工具分享SQL转ElasticSearchDSL语句

&#x1f60a; 作者&#xff1a; 瓶盖子io &#x1f496; 主页&#xff1a; 瓶盖子io-CSDN博客

vuepress-----10、vssue使用

vssue使用 https://vssue.js.org/ 按照文档 https://vssue.js.org/zh/guide/github.html (opens new window) 操作 # 1、创建 OAuth application https://github.com/settings/applications/new (opens new window) # 2、安装插件 yarn add vssue/vuepress-plugin-vssue# 这…

系统调用过程

应用程序通过系统调用请求操作系统的服务。而系统中的各种共享资源都由操作系统内核统一掌管&#xff0c;因此凡是与共享资源有关的操作&#xff08;如存储分配、/O操作、文件管理等&#xff09;&#xff0c;都必须通过系统调用的方式向操作系统内核提出服务请求&#xff0c;由…

基于javaweb实现的学籍管理系统

一、 系统架构 前端&#xff1a;jsp | jquery | css 后端&#xff1a;servlet | jstl | sqljdbc 环境&#xff1a;jdk1.6 | mysql 二、代码及数据库 三、功能介绍 01. 登录页 02. 首页 03. 修改个人密码 04. 专业信息管理 05. 班级信息管理 06. 课程信息管理 07. 学籍…

BigDecimal:高精度计算的秘密武器!

大家好&#xff0c;我是小米&#xff01;最近在面试的时候&#xff0c;发现很多公司都喜欢考察关于BigDecimal的问题&#xff0c;所以我决定在这里和大家分享一下我的经验。如果你在面试中曾经遇到过这个问题&#xff0c;或者想要更深入地了解BigDecimal&#xff0c;那就赶紧跟…

基于vue开发-创建登录页

我们使用vue创建完成项目后就开始我们的项目页面开发&#xff0c;如有不清楚怎么操作的可以看博主的前一篇文档 使用vue UI安装路由插件-CSDN博客 在src/views文件夹中创建一个登录页面 在此之前&#xff0c;我们可以先安装一个插件、element、vant、iview等等&#xff0c;可…

数据结构初阶之二叉树的详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 Linux 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力,共赴大厂。 目录 1.前言 2.二叉树各个…

智能优化算法应用:基于猎食者算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于猎食者算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于猎食者算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.猎食者算法4.实验参数设定5.算法结果6.参考文献7.…

C# WebSocket简单使用

文章目录 前言Fleck调试工具初始化简单使用 前言 最近接到了一个需求&#xff0c;需要网页实现上位机的功能。那就对数据传输的实时性要求很高。那就只能用WebSocket了。这里简单说一下我的WebSocket如何搭建 Fleck C# WebSocket(Fleck) 客户端:html Winfrom Fleck Github官网…

lorenz相图

观察Lorenz在各个不同维度上的相图。 lorenz_demo(50) function xdot g(t,x) xdot zeros(3,1); sig 10.0; rho 28.0; bet 8.0/3.0; xdot(1) sig*(x(2)-x(1)); xdot(2) rho*x(1)-x(2)-x(1)*x(3); xdot(3) x(1)*x(2)-bet*x(3); endfunction lorenz_demo(time) [t,x] ode…

软考高项第四版五组十域表+ITTO背诵笔记及助记

基于第四版做的笔记&#xff0c;助记是自己编的 还是得靠理解记忆&#xff0c;下面是文档&#xff0c;也用anki制作了记忆卡片&#xff0c;需要的可以自行导入卡包

谷歌推出功能最强大的大语言模型Gemini;大规模语言模型:从理论到实践

&#x1f989; AI新闻 &#x1f680; 谷歌推出功能最强大的大语言模型Gemini 摘要&#xff1a;谷歌正式推出其迄今为止功能最强大、最通用的大语言模型Gemini。Gemini在许多测试中表现出了最先进的性能&#xff0c;在大部分基准测试中击败了OpenAI的GPT-4。谷歌发布了三种不同…

直播录屏软件哪个好?这3款软件请你收好

随着直播文化的兴起&#xff0c;越来越多的人开始尝试通过直播平台分享自己的经验、技能和生活。在这个过程中&#xff0c;选择一款优秀的直播录屏软件变得至关重要&#xff0c;可是直播录屏软件哪个好呢&#xff1f;本文将深入介绍3款备受欢迎的直播录屏软件。通过详细的步骤指…

SQL语言重温

数据库语言重温 笔记背景SQL教程一些最重要的 SQL 命令SQL WHERE 子句SQL AND & OR 运算符SQL ORDER BY 关键字 笔记背景 由于工作需要&#xff0c;现重温简单SQL语言&#xff0c;笔记记录如下。 SQL教程 SQL&#xff08;Structured Query Language:结构化查询语言&…

[Realtek sdk-3.4.14b] RTL8197FH-VG+RTL8812FR WiFi黑名单及剔除已连接终端功能实现

sdk说明 ** Gateway/AP firmware v3.4.14b – Aug 26, 2019**  Wireless LAN driver changes as:  Refine WiFi Stability and Performance  Add 8812F MU-MIMO  Add 97G/8812F multiple mac-clone  Add 97G 2T3R antenna diversity  Fix 97G/8812F/8814B MP issu…

数字文化大观:TikTok影响下的全球文娱

在数字时代的大潮中&#xff0c;社交媒体平台正成为全球文娱产业的重要引擎之一。而TikTok&#xff0c;作为一款以短视频为特色的社交应用&#xff0c;正深刻地改变着全球文娱的面貌。 本文将深入研究TikTok对全球文娱的影响&#xff0c;探讨数字文化在这一平台的催化下如何迅…

销售技巧培训课程内容如何设计才能更好地落地

销售技巧培训课程内容如何设计才能更好地落地 在当今竞争激烈的市场环境中&#xff0c;销售人员的角色和作用越来越重要&#xff0c;是公司业绩来源的核心&#xff0c;也是公司能否在激烈竞争的市场中立于不败之地的关键。 因此&#xff0c;对销售人员进行有效的销售技巧培训&a…