Java 11的ZGC为何如此高效

Android架构中UseCase的设计原则与实战解析 本文深入解析Android架构中UseCase的设计原则与实战应用,探讨其在Domain Layer中的核心作用。通过对比ViewModel的臃肿问题,详细阐述UseCase的无状态原则、单一职责边界等设计铁律,并提供多种实现方式的代码示例,帮助开发者构建更清晰、高效的Android应用架构。 阅读详情

Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。
Java 11包含一个全新的垃圾收集器–ZGC,它由Oracle开发,承诺在数TB的堆上具有非常低的暂停时间。 在本文中,我们将介绍开发新GC的动机,技术概述以及由ZGC开启的一些可能性。
那么为什么需要新GC呢?毕竟Java 10已经有四种发布多年的垃圾收集器,并且几乎都是无限可调的。 换个角度看,G1是2006年时引入Hotspot VM的。当时最大的AWS实例有1 vCPU和1.7GB内存,而今天AWS很乐意租给你一个x1e.32xlarge实例,该类型实例有128个vCPU和3,904GB内存。 ZGC的设计目标是:支持TB级内存容量,暂停时间低(<10ms),对整个程序吞吐量的影响小于15%。 将来还可以扩展实现机制,以支持不少令人兴奋的功能,例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存),或压缩堆。
GC术语
为了理解ZGC如何匹配现有收集器,以及如何实现新GC,我们需要先了解一些术语。最基本的垃圾收集涉及识别不再使用的内存并使其可重用。现代收集器在几个阶段进行这一过程,对于这些阶段我们往往有如下描述:
• 并行- 在JVM运行时,同时存在应用程序线程和垃圾收集器线程。 并行阶段是由多个gc线程执行,即gc工作在它们之间分配。 不涉及GC线程是否需要暂停应用程序线程。
• 串行- 串行阶段仅在单个gc线程上执行。与之前一样,它也没有说明GC线程是否需要暂停应用程序线程。
• STW - STW阶段,应用程序线程被暂停,以便gc执行其工作。 当应用程序因为GC暂停时,这通常是由于Stop The World阶段。
• 并发 -如果一个阶段是并发的,那么GC线程可以和应用程序线程同时进行。 并发阶段很复杂,因为它们需要在阶段完成之前处理可能使工作无效(译者注:因为是并发进行的,GC线程在完成一阶段的同时,应用线程也在工作产生操作内存,所以需要额外处理)的应用程序线程。
• 增量 -如果一个阶段是增量的,那么它可以运行一段时间之后由于某些条件提前终止,例如需要执行更高优先级的gc阶段,同时仍然完成生产性工作。 增量阶段与需要完全完成的阶段形成鲜明对比。
权衡
值得指出的是,所有这些属性都需要权衡利弊。 例如,并行阶段将利用多个gc线程来执行工作,但这样做会导致线程协调的开销。 同样,并发阶段不会暂停应用程序线程,但可能涉及更多的开销和复杂性,才能同时处理使其工作无效的应用程序线程。
ZGC
现在我们了解了不同gc阶段的属性,让我们继续探讨ZGC的工作原理。 为了实现其目标,ZGC给Hotspot Garbage Collectors增加了两种新技术:着色指针和读屏障。
着色指针
着色指针是一种将信息存储在指针(或使用Java术语引用)中的技术。因为在64位平台上(ZGC仅支持64位平台),指针可以处理更多的内存,因此可以使用一些位来存储状态。 ZGC将限制最大支持4Tb堆(42-bits),那么会剩下22位可用,它目前使用了4位: finalizable, remap, mark0和mark1。 我们稍后解释它们的用途。
着色指针的一个问题是,当您需要取消着色时,它需要额外的工作(因为需要屏蔽信息位)。 像SPARC这样的平台有内置硬件支持指针屏蔽所以不是问题,而对于x86平台来说,ZGC团队使用了简洁的多重映射技巧。
多重映射
要了解多重映射的工作原理,我们需要简要解释虚拟内存和物理内存之间的区别。 物理内存是系统可用的实际内存,通常是安装的DRAM芯片的容量。 虚拟内存是抽象的,这意味着应用程序对(通常是隔离的)物理内存有自己的视图。 操作系统负责维护虚拟内存和物理内存范围之间的映射,它通过使用页表和处理器的内存管理单元(MMU)和转换查找缓冲器(TLB)来实现这一点,后者转换应用程序请求的地址。
多重映射涉及将不同范围的虚拟内存映射到同一物理内存。 由于设计中只有一个remap,mark0和mark1在任何时间点都可以为1,因此可以使用三个映射来完成此操作。 ZGC源代码中有一个很好的图表可以说明这一点。
读屏障
读屏障是每当应用程序线程从堆加载引用时运行的代码片段(即访问对象上的非原生字段non-primitive field):

void printName( Person person ) {
String name = person.name; // 这里触发读屏障
// 因为需要从heap读取引用
//
System.out.println(name); // 这里没有直接触发读屏障
}

在上面的代码中,String name = person.name 访问了堆上的person引用,然后将引用加载到本地的name变量。此时触发读屏障。 Systemt.out那行不会直接触发读屏障,因为没有来自堆的引用加载(name是局部变量,因此没有从堆加载引用)。 但是System和out,或者println内部可能会触发其他读屏障。
这与其他GC使用的写屏障形成对比,例如G1。读屏障的工作是检查引用的状态,并在将引用(或者甚至是不同的引用)返回给应用程序之前执行一些工作。 在ZGC中,它通过测试加载的引用来执行此任务,以查看是否设置了某些位。 如果通过了测试,则不执行任何其他工作,如果失败,则在将引用返回给应用程序之前执行某些特定于阶段的任务。
标记
现在我们了解了这两种新技术是什么,让我们来看看ZG的GC循环。
GC循环的第一部分是标记。标记包括查找和标记运行中的应用程序可以访问的所有堆对象,换句话说,查找不是垃圾的对象。
ZGC的标记分为三个阶段。 第一阶段是STW,其中GC roots被标记为活对象。 GC roots类似于局部变量,通过它可以访问堆上其他对象。 如果一个对象不能通过遍历从roots开始的对象图来访问,那么应用程序也就无法访问它,则该对象被认为是垃圾。从roots访问的对象集合称为Live集。GC roots标记步骤非常短,因为roots的总数通常比较小。
在这里插入图片描述
该阶段完成后,应用程序恢复执行,ZGC开始下一阶段,该阶段同时遍历对象图并标记所有可访问的对象。 在此阶段期间,读屏障针使用掩码测试所有已加载的引用,该掩码确定它们是否已标记或尚未标记,如果尚未标记引用,则将其添加到队列以进行标记。
在遍历完成之后,有一个最终的,时间很短的的Stop The World阶段,这个阶段处理一些边缘情况(我们现在将它忽略),该阶段完成之后标记阶段就完成了。
重定位
GC循环的下一个主要部分是重定位。重定位涉及移动活动对象以释放部分堆内存。 为什么要移动对象而不是填补空隙? 有些GC实际是这样做的,但是它导致了一个不幸的后果,即分配内存变得更加昂贵,因为当需要分配内存时,内存分配器需要找到可以放置对象的空闲空间。 相比之下,如果可以释放大块内存,那么分配内存就很简单,只需要将指针递增新对象所需的内存大小即可。
ZGC将堆分成许多页面,在此阶段开始时,它同时选择一组需要重定位活动对象的页面。选择重定位集后,会出现一个Stop The World暂停,其中ZGC重定位该集合中root对象,并将他们的引用映射到新位置。与之前的Stop The World步骤一样,此处涉及的暂停时间仅取决于root的数量以及重定位集的大小与对象的总活动集的比率,这通常相当小。所以不像很多收集器那样,暂停时间随堆增加而增加。
移动root后,下一阶段是并发重定位。 在此阶段,GC线程遍历重定位集并重新定位其包含的页中所有对象。 如果应用程序线程试图在GC重新定位对象之前加载它们,那么应用程序线程也可以重定位该对象,这可以通过读屏障(在从堆加载引用时触发)实现,如流程图如下所示:
在这里插入图片描述
这可确保应用程序看到的所有引用都已更新,并且应用程序不可能同时对重定位的对象进行操作。
GC线程最终将对重定位集中的所有对象重定位,然而可能仍有引用指向这些对象的旧位置。 GC可以遍历对象图并重新映射这些引用到新位置,但是这一步代价很高昂。 因此这一步与下一个标记阶段合并在一起。在下一个GC周期的标记阶段遍历对象对象图的时候,如果发现未重映射的引用,则将其重新映射,然后标记为活动状态。
概括
试图单独理解复杂垃圾收集器(如ZGC)的性能特征是很困难的,但从前面的部分可以清楚地看出,我们所碰到的几乎所有暂停都只依赖于GC roots集合大小,而不是实时堆大小。标记阶段中处理标记终止的最后一次暂停是唯一的例外,但是它是增量的,如果超过gc时间预算,那么GC将恢复到并发标记,直到再次尝试。
性能
那ZGC到底表现如何?
Stefan Karlsson和Per Liden在今年早些时候的Jfokus演讲中给出了一些数字。 ZGC的SPECjbb 2015吞吐量与Parallel GC(优化吞吐量)大致相当,但平均暂停时间为1ms,最长为4ms。 与之相比G1和Parallel有很多次超过200ms的GC停顿。
然而,垃圾收集器是复杂的软件,从基准测试结果可能无法推测出真实世界的性能。我们期待自己测试ZGC,以了解它的性能如何因工作负载而异。
未来的可能性
着色指针和读屏障提供了一些有趣的可能。
多层堆和压缩
随着闪存和非易失性存储器变得越来越普遍,一种可能是JVM中允许多层堆,可以让很少使用的对象存储在较慢的存储层上。
该功能可以通过扩展指针元数据来实现,指针可以实现计数器位并使用该信息来决定是否需要移动对象到较慢的存储上。如果将来需要访问,则读屏障可以从存储中检索到对象。
或者对象可以以压缩形式保存在内存中,而不是将对象重定位到较慢的存储层。当请求时,可以通过读屏障将其解压并重新分配。
ZGC的状态

在撰写本文时,ZGC仍然是实验性的。
您可以使用Java 11 Early Access版本( http://jdk.java.net/11/ )进行测试,但值得指出的是,可能需要一段时间才能解决新版本中的所有问题。对于垃圾收集器来说,从G1发布到最终支持之间超过三年。
概要
随着拥有数百GB到数TB RAM的服务器变得越来越普及,Java有效使用该规模堆的能力变得越来越重要。
ZGC是个令人兴奋的新垃圾收集器,旨在为大堆提供非常低的暂停时间。 它通过使用着色指针和读屏障来实现这一点,这些是Hotspot新近开发的GC技术,并为未来增加了很多可能性。 ZGC在Java 11中作为实验性的功能提供,现在可以使用Early Access 版本试用。

手把手教你用STM32单片机DIY一个简易PLC(附完整电路图与PCB文件) 本文详细介绍了如何利用STM32单片机DIY一个简易PLC控制器,涵盖硬件设计、电路图解析、PCB布局优化及固件框架实现。通过完整的电路图和PCB文件,帮助读者从元器件选型到工业级优化,逐步构建可靠的PLC系统,特别适合工业自动化爱好者和学习者实践。 阅读详情

相关推荐

九齐NY8B062F单片机:12位ADC与4路PWM在智能家居控制中的实战应用

本文详细介绍了九齐NY8B062F单片机在智能家居控制中的实战应用,重点解析其12位ADC高精度传感器数据采集和4路PWM精准驱动技术。通过实际案例展示如何利用该单片机实现温湿度监测、灯光调节及电机控制,并分享低功耗设计与抗干扰方案,为低成本高可靠性的智能家居设备开发提供完整解决方案。

rnn9storyteller的博客 730

JVM — JDK11垃圾回收器 ZGC

ZGC(The Z Garbage Collector)是 JDK 11 中推出的一款低延迟垃圾回收器,为实现以下几个目标而诞生的垃圾回收器,停顿时间不超过 10ms,停顿时间不会因堆变大而变长,支持 8MB~4TB 级别的堆(未来支持 16TB)ZGC 作为下一代垃圾回收器,性能非常优秀。ZGC 垃圾回收过程几乎全部是并发,实际 STW 停顿时间极短,不到 10ms。这得益于其采用的着色指针和读屏障技术。

qq_38658567的博客 3825

网络调试和分析工具 Proxyman Premium

它支持MacOS、iOS和iPadOS等操作系统,提供丰富的功能,如查看和编辑HTTP/HTTPS请求和响应、设置断点、过滤请求等。Proxyman Premium还支持WebSocket、GraphQL和gRPC等现代网络协议调试,并通过直观且图形化的操作界面,使用户能高效地监控和操纵网络数据流。此外,它还具备多种高级功能,如WebSocket支持、DNS欺骗、自定义SSL证书等,为开发人员提供极大的便利。同时,由于软件版本更新和界面调整,上述步骤可能会有所变化,建议您参考最新版本的官方文档进行操作。

llhf688的博客 2000

JVM11 垃圾回收

而且在限定单核cpu才可以用。现在都不是单核的了。对于交互较强的应用而言,这种垃圾收集器是不能接受的。一般在Java web应用程序中是不会采用串行垃圾收集器的。截止JDK1.8,一共有7款不同的垃圾收集器。每一款的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。GC发展阶段:Seria l=> Parallel(并行)=> CMS(并发)=> G1 => ZGC不同厂商、不同版本的虚拟机实现差距比较大。

欧气满满大顺顺的博客 929

使用项目管理画布启动项目

许多人对商业模式画布并不陌生,它是亚历山大·奥斯特瓦德(Alexander Osterwalder)、伊夫·皮尼厄(Yves Pigneur)在《商业模式新生代》(Business Model Generation)中提出的一种用来描述商业模式、可视化商业模式、评估商业模式以及改变商业模式的通用语言。 在我们做敏捷软件项目inception(项目启动规划)的时候经常会用到商业画布,此时它的作用是帮助我们快速了解客户的业务、产品和市场,帮助客户梳理自己的资源、优势和盈利模式,总的来说,商业画布是一种简单实用的

IDEAL Garden 1224

ElasticSearch 集群安全加固实战:从零配置TLS证书与密码认证

本文提供了一份详尽的ElasticSearch集群安全加固实战指南,重点介绍了如何从零开始配置TLS证书与用户安全认证。通过分步讲解证书生成、节点配置、集群重启及密码设置,帮助管理员为ES集群构建通信加密与访问控制的双重防线,有效提升数据安全性与合规性。

weixin_29323493的博客 444

一文读懂Java 11的ZGC为何如此高效

原文地址  https://mp.weixin.qq.com/s/nAjPKSj6rqB_eaqWtoJsgw   一文读懂Java 11的ZGC为何如此高效 原创: Sadiq Jaffer等 高可用架构 昨天 导读:GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他...

weixin_39639119的博客 6093

三极管、MOS管和晶体管综合对比——《器件手册--三极管、MOS管和晶体管》

IGBT(Insulated Gate Bipolar Transistor,绝缘栅双极型晶体管)是一种复合全控型电压驱动式功率半导体器件,结合了MOSFET的高输入阻抗、开关速度快的优点和双极型晶体管(BJT)的低导通压降、高电流密度的优点。例如,在NPN型三极管中,当基极电流增加时,集电极电流会按照一定的比例(放大倍数β)增加,这个比例通常在几十到几百之间。在NMOS管中,当栅极相对于源极的电压(Vgs)小于开启电压(Vth)时,漏极和源极之间没有导电沟道,电流无法通过,处于截止状态。

XU157303764的博客 2881

Java11--ZGC--权衡--ZGC--GC术语--着色指针--多重映射--读屏障标记--重定位

标记阶段中处理标记终止的最后一次暂停是唯一的例外,但是它是增量的,如果超过gc时间预算,那么GC将恢复到并发标记,直到再次尝试。并发阶段很复杂,因为它们需要在阶段完成之前处理可能使工作无效(译者注:因为是并发进行的,GC线程在完成一阶段的同时,应用线程也在工作产生操作内存,所以需要额外处理)的应用程序线程。值得指出的是,所有这些属性都需要权衡利弊。在遍历完成之后,有一个最终的,时间很短的的Stop The World阶段,这个阶段处理一些边缘情况(我们现在将它忽略),该阶段完成之后标记阶段就完成了。

业精于勤,荒于嬉 788

YOLOv11改进-上采样 | EUCB高效上卷积块,实现特征图尺度匹配和高效上采样

本文介绍了一种在YOLOv11目标检测模型中引入高效解码器模块EMCAD的创新方法,以提升模型在资源受限场景下的性能与效率。EMCAD由多个模块构成,其中核心的EUCB(高效上卷积块)通过上采样、深度可分离卷积、激活归一化和通道调整等操作,兼顾了特征质量与计算成本。实验结果显示,该模块在显著减少参数与FLOPs的同时仍具备优异性能。文章还提供了完整的YOLOv11模型集成流程、配置和训练实战。

魔改工程师的博客 1540

ACC自适应巡航系统

ACC自适应巡航系统可在高速驾驶情况下,自动控制纵向跟车距离,减轻驾驶员的工作量。该功能主要依靠安装在车辆前挡风玻璃上的摄像头和布置在格栅附近的雷达进行融合实现。

未知艺术家的博客 203

JDK11-G1垃圾收集器

原文在这里:https://docs.oracle.com/en/java/javase/11/gctuning/garbage-first-garbage-collector.html G1垃圾收集器简介 The Garbage-First (G1) garbage collector is targeted for multiprocessor machines with a large am...

若鱼的专栏 1万+

Allegro172版本如何在联机模式下使用skill文件操作指导

注意:如果下次重新开启Symphony模式的时候可能导致symphony_skill中的文件内容被清空,所以最好将自己常用的skill文件都写到symphony_skill.txt中去,然后做好备份,需要的时候,在开启软件后把文件放到env目录中去。在用Allegeo172版本进行PCB设计的时候,有时会用到Symphony模式进行多人实时在线协同设计,如下图。这个模式设计起来可以提升设计速度,但是也有一个缺陷,就是不能使用skill文件。如下图,当调用skill的时候就会出现如下报错。

weixin_54787054的博客 1586

java11开启 zgc_一文读懂Java 11的ZGC为何如此高效

导读:GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他可能性做了展望。ZGC是否可以达到该性能目标,请看高可用架构志愿者翻译的文章。Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。Java 11包含一个全新的垃圾收集器–ZGC,它由Ora...

weixin_30496435的博客 1028

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

java11zgc_一文读懂Java 11的ZGC为何如此高效

导读:GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他可能性做了展望。ZGC是否可以达到该性能目标,请看高可用架构志愿者翻译的文章。Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。Java 11包含一个全新的垃圾收集器–ZGC,它由Ora...

weixin_42516490的博客 149

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

一语道破Java 11的ZGC为何如此高效

GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他可能性做了展望。ZGC是否可以达到该性能目标,请看高可用架构志愿者翻译的文章。 Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。 Java 11包含一个全新的垃圾收集器–ZGC...

dijianlian9563的博客 161

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

对讲机为何只能一句一答?半双工与全双工的通信原理揭秘

双工方式决定了无线通信设备能否实现同时收发。从对讲机的半双工到手机的全双工,背后涉及PTT按键机制、FDD/TDD技术路线以及频谱资源分配等核心概念。理解半双工,不仅有助于解释对讲机为何必须“一句一答”,也能帮助排查无线网络卡顿、Wi-Fi掉速等实际问题。文章从最基础的通信原理出发,介绍单工、半双工、全双工的区别,分析对讲机采用半双工的成本、频谱与调度原因,并延伸到4G/5G基站的FDD/TDD设计,最后给出对讲机使用与写频的实操建议,帮助现场人员与运维新人快速掌握这一无线通信核心知识点。

weixin_34174422的博客 661

Java11 高效垃圾回收器-ZGC

一:ZGC介绍 ZGC 是最新的 JDK1.11 版本中提供的高效垃圾回收算法,ZGC 针对大堆内存设计可以支持 TB 级别的堆,ZGC 非常高效,能够做到 10ms 以下的回收停顿时间。 ZGC实现的依赖技术: 着色指针 着色指针是一种将信息存储在指针(或使用Java术语引用)中的技术。因为在64位平台上(ZGC仅支持64位平台),指针可以处理更多的内存,因此可以使用一些位来存储状态。 ZG...

tiger-guo 1199

一文读懂 Java 11 的 ZGC 为何如此高效

要了解多重映射的工作原理,我们需要简要解释虚拟内存和物理内存之间的区别。标记阶段中处理标记终止的最后一次暂停是唯一的例外,应用程序线程,但可能涉及更多的开销和复杂性,才能同时处理使其工作无效的。着色指针的一个问题是,当您需要取消着色时,它需要额外的工作(因为需要屏。图并标记所有可访问的对象。载的引用,该掩码确定它们是否已标记或尚未标记,如果尚未标记引用,则将其。致了一个不幸的后果,即分配内存变得更加昂贵,因为当需要分配内存时,内存。标记阶段遍历对象对象图的时候,如果发现未重映射的引用,则将其重新映射,

m0_59281987的博客 154

[No0000196]一文读懂Java 11的ZGC为何如此高效

导读:GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他可能性做了展望。ZGC是否可以达到该性能目标,请看高可用架构志愿者翻译的文章。 Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。 Java 11包含一个全新的垃圾收集器...

weixin_30681615的博客 120

java解释执行与高性能_一语道破Java 11的ZGC为何如此高效

GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析。同时还对还对这一新功能带来的其他可能性做了展望。ZGC是否可以达到该性能目标,请看高可用架构志愿者翻译的文章。Java 11的新功能已经完全冻结,其中有些功能绝对非常令人兴奋,本文着重介绍ZGC。Java 11包含一个全新的垃圾收集器–ZGC,它由Oracle...

weixin_42515409的博客 340
上一篇: Mybatis详细入门介绍
下一篇: 如何学习java
HelloWorld_AA
博客等级 码龄9年 18粉丝 96原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值