摸鱼JVM - 垃圾收集

关于 Java 的简介(评论抽奖送书) 💂 个人网站:【海拥】【摸鱼小游戏】【开发文档导航】 🤟 风趣幽默的人工智能学习网站:👉人工智能 💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 💬 免费且实用的Java刷题(面经大全)网站:👉点击跳转到网站 直接跳到末尾 参与评论送书 JAVA 由 Sun Microsystems Inc 的 James Gosling 于1995 年开发,后来被 Oracle Corporation 收购。它是一种简单的编程语言。Java 使编写、编译和调试编程变得容易。它有助于创建可重用的代码和模.. 阅读详情

前言

谈起JVM, 那么就不得不提垃圾收集(Garbage Collection 通常被称为“GC”).

什么是垃圾收集呢?

想解答这个问题, 我们最好将问题拆解开

  • 如何确定垃圾?
  • 如何回收垃圾?
  • 何时回收垃圾?

下面围绕这三件事, 我们站在JVM层面梳理下垃圾收集的机制.

如何确定垃圾?

从JVM层面来看, 它管理的是生命周期内的全部实例对象, 那么所谓的垃圾其实就是“无用的对象”.

那么它是如何确定“无用对象”的?

引用计数法

在 Java 中,引用和对象是有关联的, 必须使用引用来操作对象.

People zs = new People();
zs.setName(“张三”);
zs是个引用, 和真正的对象“new People()”关联

因此, 简单的办法是通过引用计数来判断一个对象是否可以回收.

所以在JVM中, 每个对象都在对象头结构中维护了一个引用计数属性

  • 对象被引用一次时, 计数就加1
  • 对象的引用被释放时,计数就减1
  • 对象的计数为0的时, 这个对象就可以被回收了

引用计数法听着虽然简单易懂, 判定效率也高.
但是,当前主流的虚拟机都没有采用这个算法来管理内存,其中最主要的原因是它很难解决对象之间互相循环引用的问题.

循环引用问题

所谓对象之间互相循环引用,如下面代码所示:
除了对象 objA 和 objB 相互引用着对方之外,这两个对象之间再无任何引用.
但是它们因为互相引用对方,导致它们的引用计数器都不为 0,于是引用计数算法无法通知 GC 回收器回收他们.

PS: 实际上以下示例是能回收的, 因为JVM没有采用引用计数法

public class ReferenceCountingGc {
    public Object instance = null;

    public static void main(String[] args) {
        ReferenceCountingGc obj1 = new ReferenceCountingGc();
        ReferenceCountingGc obj2 = new ReferenceCountingGc();
        obj1.instance = obj2;
        obj2.instance = obj1;
        obj1 = null;
        obj2 = null;
    }
}
可达性分析

为了解决引用计数法的循环引用问题, Java 使用了可达性分析的方法.

可达性分析就是通过一系列的称为 “GC Roots”的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链.
当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的.

如下图中的 Object 6 ~ Object 10 之间虽有引用关系,但它们到 GC Roots 不可达, 因此为需要被回收的对象.

image.png

在Java中, GC Roots包括:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈(Native 方法)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁持有的对象

要注意的是:

  • 不可达对象不等价于可回收对象
  • 不可达对象变为可回收对象至少要经过两次标记过程,两次标记后仍然是可回收对象,则将面临回收

如何回收垃圾?

确定垃圾, 那么如何回收呢?
这就不得不谈一系列的垃圾回收算法, 算法实现会因各个平台虚拟机的差异而不同, 这里我们只谈几种主流的算法思想.

标记-清除算法 (Mark-Sweep)

这是最基础的收集算法, 分为标记、清除两个阶段
主要算法思想就是

通过算法标记出回收对象(举例: hotspot使用可达性分析),进而回收标记的对象占用的空间

image.png

从示例图不难看出, 该算法的最大缺陷就

  • 内存碎片化

后续碰到分配大对象时(连续的内存空间), 必然导致内存不够从而触发额外的GC.

另外就是标记和清除两个过程本身的效率都不高.

标记-复制算法(copying)

复制算法算是Mark-Sweep算法的升级版, 主要就是为了解决Mark-Sweep算法“内存碎片化”的问题.

该算法的主要思想如下

按内存容量将内存划分为等大小的两块. 每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去, 把已使用的内存清掉.

image.png

这种算法虽然实现简单,内存效率高,不易产生碎片,但是存在两个较严重问题

  • 可用内存被压缩到了原来的一半

  • 存活对象较多的话, Copying算法的效率较低

标记-整理算法(Mark-Compact)

为了解决以上两种算法的缺陷, 进而提出了标记整理算法.

算法的主要思想如下

分为标记、整理两个阶段
标记阶段和Mark-Sweep相同, 不同点是标记后不会清理对象, 而是将存活对象移向内存的一端.
然后清除端边界外的对象.
image.png

分代收集算法

上面介绍了几个算法都各有优缺点, 但没有哪个是绝对优势的.
只能说每个算法都有各自的应用场景.

而在JVM垃圾回收领域, 面对各种内存回收的复杂场景, 显然, 不可能存在一种算法就能达到最优解.

此时聪明的开发者就提出了一种想法, 既然无法“一招通杀”, 那么, 我就“分而治之”.

通过一定规则把内存区域划成几块, 这样某些小块的内存回收场景就存在某个“最优解回收算法”, 每块都是最优解, 那么总体上不就是最优解么?!

于是, 分代收集算法应运而生.

严格来说, 分代收集算法并不是个垃圾回收算法, 而是把对象按生命周期来进行内存划分的思想.

该算法的主要思想如下

根据对象存活的不同生命周期, 将内存划分为几块不同的区域.
一般情况下将Java堆划分为新生代和老年代

  • 新生代的对象特点是大部分对象都是朝生夕死,生命周期很短, 每次垃圾回收时有大量对象需要被回收

  • 老年代的对象特点是生命周期较长,每次垃圾回收时只有少量对象需要被回收

结合新生代、老年代的特点, 于是适配了合适的垃圾回收算法

新生代与复制算法

目前大部分JVM 的 GC 对于新生代都采取 Copying 算法,

因为新生代每次垃圾回收都要回收大部分死亡对象,存活的对象少, 所以要复制的操作比较少.
这样的特点刚好能发挥Copying 算法的效率.

新生代的划分并没有严格按Copying 算法的1:1划分法, 而是将新生代划分为一块较大的 Eden区和两个较小的 Survivor区(From区, To区)(一般也称为S1和S2区),
默认内存占比为 Eden:S1:S2 是8:1:1

image.png

每次使用Eden区和其中的一块 Survivor 区,当进行垃圾回收时,将该两块区中还存活的对象复制到另一块 Survivor区中.

老年代与标记整理算法

老年代本身存放的对象都是熬过了一轮轮GC的, 都是“存活几率”较高的, 老年代最终存放着大量的对象, 所以每次只需对少量死亡对象进行回收, 因而采用 Mark-Compact 算法.

一次完整的GC过程如下

实例理解:

  • 新New的对象一般出现在Eden区

    • PS: 少数大对象(需要连续的内存空间) 会直接进老年代
    • PS: Hotspot可配置: -XX:PretenureSizeThreshold=2m , 即2m以上的对象直接进老年代
  • 慢慢的Eden区满了, 此时触发一次GC, 将还存活的对象复制到某个空的S区, 称为S1区

    • PS: S1和S2身份随时互换, 只有空的我们称为S1区, 两个S区必然有一个是空的
    • PS: 也就是假设年轻代空间比例8:1:1
  • 慢慢的S1区也满了, 此时触发GC, 已满的S1区和Eden区还存活的对象

  • 对象的内存分配主要在新生代的 Eden区和 From区, 少数情况(比如new了个大对象, 新生代放不下了)会直接分配到老生代

  • 当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,Eden Space 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 From Space 进行清理。

  • 如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。

  • 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环。

  • 当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。默认情况下年龄到达 15 的对象会被 移到老生代中。

请关注我的订阅号

订阅号.png

参考

  • 《深入理解JAVA虚拟机:JVM高级特性与最佳实践》
DEA各种模型原理及stata代码实现 DEA各种模型原理及stata代码实现DEA各种模型原理及stata代码实现一、CCR和BCC1.原理2.效率测算stata代码3.Malmquist指数3.1M指数3.2Global-Malmquist指数4.指数计算代码与案例二、SBM模型1.原理2.stata代码实现三、方向性距离函数(DDF)1.原理2.stata代码实现3.非径向DDF模型(NDDF)3.GML指数4.指数测算四、总结 DEA各种模型原理及stata代码实现 一、CCR和BCC 1.原理 CCR模型产出导向下的效率通过求解以下规划 阅读详情

相关推荐

通过ssh进行宇树g1机器人进行连接

原因:就是g1机器人输出接口损坏,无法连接外部显示器。前期准备:本文电脑是联想Y7000p(windows)2.进入页面后:3.出现是一个压缩包,解压后:4.安装时:要注意,需要在文件夹中找到这个文件目录,然后在此鼠标右键开启终端进行安装:接着按照提示next下去即可,可以自定义安装路径。

m0_72207463的博客 1282

JUC、JVM

什么是juc?JUC就是java.util.concurrent工具包的简称。这是一个处理线程的工具包。提供了许多在并发编程工程中常用的工具类,用于定义类似于线程的自定义子系统,包括线程池、异步IO、轻量级框架、还提供了多线程上下文的Collectiion的实现。什么是进程和线程?一个软件一个进程,一个进程有许多的线程。进程——资源分配最小单位  线程——程序执行最小单位New 新建状态(线程刚被创建,start方法之前的状态)

qq_42012853的博客 2028

DBeaver连接IoTDB避坑指南:手动配置JDBC驱动的完整流程(附问题排查)

本文提供了在DBeaver中手动配置Apache IoTDB JDBC驱动的完整流程与避坑指南。详细解析了从驱动创建、库文件添加(关键是指向整个lib目录)到连接测试的每一步,并重点针对常见的ClassNotFoundException、连接拒绝等错误提供了深度排查方案,帮助用户高效建立图形化管理连接。

weixin_28327051的博客 393

【java】走进JVM,浅水也能摸鱼

这不是一篇描述jvm是什么的文章,也不介绍jvm跨平台的特性,也不是讲述jvm安全特性的文章,更不是讲解jvm指令操作,数据运算的文章,本文重点讲述类型的生命周期。 类型的生命周期涉及到:类的装载、jvm体系结构、垃圾回收机制。 为什么要讲jvm体系结构?因为类的装载和垃圾回收机制都和jvm体系结构息息相关。 那么什么是jvm体系结构呢? 当jvm运行起来的时候,它会向系统申请一片内存

Coder,梦到了梦 829

ESP32+micro-ROS机器人开发实战:轻量级ROS2嵌入式集成

ROS2是现代机器人软件栈的核心框架,其基于DDS的分布式通信与QoS保障能力为多节点协同提供基础支撑;而micro-ROS作为专为微控制器优化的ROS2兼容中间件,解决了资源受限设备(如ESP32)接入ROS2生态的关键难题。其通过分层架构将DDS通信下沉至上位机Agent,使MCU仅需运行轻量Client,大幅降低内存开销(实测<180KB)并保留标准ROS2接口语义。该方案广泛应用于教育机器人、移动底盘、传感器节点等嵌入式场景,尤其适合基于ESP-IDF开发的Wi-Fi/BLE物联网机器人系统。本文以

weixin_29025501的博客 398

VS2015+C++实战:手把手教你用海康MVS里的Demo搞定多相机同步采图与保存

本文详细解析了在VS2015+C++环境下,利用海康威视MVS工业相机SDK实现多相机同步采图与保存的全流程。从环境准备、SDK选择到多相机初始化、同步采图方案,再到异常处理与性能优化,提供了实战技巧和代码示例,帮助开发者快速掌握工业相机二次开发的核心技术。

weixin_29170327的博客 280

JVM篇4:详解JVM调优与经典案例分析

JVM调优介绍以及案例分析

m0_59624833的博客 1576

2024最新版Anaconda Navigator安装使用指南

本文简要介绍如何下载安装Anaconda Navigator最新版,以及如何使用Python内核搭载来完成应用程序开发。

jackson_lingua的博客 1万+

JVM垃圾回收机制算法详解

带你揭开Java垃圾回收机制的神秘面纱Java垃圾回收机制是面试的一大难点,但是别慌,都是小场面总述何为垃圾?怎么确定垃圾?引用计数算法可达性分析算法怎么回收垃圾?标记-清除算法复制算法标记-整理算法分代收集算法总结: Java垃圾回收机制是面试的一大难点,但是别慌,都是小场面 废话不多说,直接上图 总述 本文按照 何为垃圾 -> 怎么确定垃圾 -> 怎么回收垃圾 路线来介绍Java...

plutomate的博客 298

SOME/IP协议详解「总目录」

SOME/IP系列文章总目录

雪云飞星的博客 2万+

【OpenClaw从入门到精通】第04篇:Web/TUI/钉钉全打通!OpenClaw多端交互实测指南(2026避坑版)

本文详解OpenClaw三大交互方式(Web控制台、TUI终端、钉钉集成),解决新手多端操作难题。Web控制台适合可视化深度配置,TUI终端满足服务器高效运维,钉钉集成实现移动办公协同。提供2026实测配置步骤、代码示例及避坑指南,涵盖设备配对、终端命令优化、聊天机器人回调验证等核心场景,助用户快速掌握"随时召唤AI助理"的全链路方案。 关键词 OpenClaw、多端交互、Web控制台、TUI终端、钉钉集成、AI助理、实操指南 核心亮点 全链路打通:覆盖Web/TIM/IM三端配置

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 3542

34、垃圾回收算法 、 分代GC

JVM的分代垃圾回收算法主要通过将堆内存分为年轻代和老年代来优化垃圾回收的性能,分别使用不同的回收策略(复制算法、标记-清除、标记-整理)来处理不同生命周期的对象。通过这种方式,JVM能够高效地管理内存并减少垃圾回收带来的性能开销。

qq_41577703的博客 860

C#串口通信从入门到精通(11)——串口接收的数据存储到本地文件(txt、csv)

本文详细介绍如何将串口通信将数据进行本次存储,主要介绍常用的csv、txt格式文件,由多年实战经验总结,绝对干货!

qq_34059233的博客 7237

JVM 面试问题,背完去面试(面试篇 一)

首先声明,该博客用于对JVM有了解的人,本文也是根据B站某班的老师讲的内容,进行了总结。将概念理论,大家自己去查找,我也可以发你地址(很多视频,不说讲的不好,实在是在摸鱼,纯粹浪费时间,而有些博客写的实在是看不下去,还是错的)。 基于我自己的理解,做了一些简单的总结,你可以背完去面试,但是不建议。很多东西你得有自己的认识,下面涉及的很多概念,都需要一定的基础。 - 谈谈你对JVM的认识。题目很大,等于没问 1. 首先,JVM(Java Virtual Machine)java虚拟机,但是也不能说只能运

dadachenchen的博客 467

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

jvm gc的理解

jvmGC串行GC并行GCCMS GCG1 堆的GC就像一个公司的管理体系 年轻代就是实习生和新员工 老年代就是老员工 年轻代和老年代的默认比例是1:2 年轻代里有新生区和两个存活区比例是8:1 :1 一个公司要招一批新的实习生进这个新生区进行锻炼,当这个新生区满的时候就要进行第一次选拔就是我们的ygc 这时会选出一批合适的实习生可达的进入考核区一个存活区内其余不合适的实习生不可达的对象全部淘汰 考核中可能出现的情况 : 1.如果有一个部门的一组实习生们大对象都特别优秀,他们便直接晋升为老员工老年代 2.其

weixin_42194515的博客 251

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

看完这一篇大部分的初学者都不会深入了解的JVM垃圾回收算法,赢在起跑线。

方法区中类静态属性引用的对象 方法区中的常量引用的对象 [](()3.finalize Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(),可以完成对象的拯救(不被回收),但是不能保证一定不被回收,说白了就是没啥用,一个坑。 [](()三、各种引用(Reference) Reference 中存储的数据代表的是另一块内存的起始 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】..

m0_69526738的博客 244

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

阿里一面:每天100w次登陆请求, 8G内存如何设置JVM参数?

日喀则市 · 珠穆朗玛峰国家级自然保护区就在上周,一个同学在阿里云技术面终面的时候被问到这么一个问题:假设一个每天100w次登陆请求的平台,一个服务节点 8G 内存,该如何设置JVM参数?。下面以面试题的形式给大家梳理出来,做到一箭双雕:既供大家实操参考又供大家面试参考大家要学习的,除了 JVM 配置方案 之外,是其 分析问题的思路、思考问题的视角。这些思路和视角,能帮助大家走更远、更远。接下...

Java精选 199

Java面试-常见的垃圾回收器:Serial、Parallel、CMS、G1、ZGC

《Java垃圾回收器深度解析》摘要:本文系统梳理Java五大主流垃圾回收器(Serial、Parallel、CMS、G1、ZGC)的工作原理与适用场景。通过生动比喻(如Serial是"单兵作战的扫街大爷")、流程图解和代码示例(如ParallelGC配置),深入解析各回收器特点:从单线程的Serial到追求吞吐量的Parallel,从低停顿的CMS到分区收集的G1,再到革命性的ZGC。文章包含GC参数配置指南、决策树和面试高频问题,帮助开发者根据应用场景(内存大小、延迟要求等)选择最优回

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

上班摸鱼在群里吹牛B,逮到一个华为10年老Java开发,聊过之后收益良多

这份面试题几乎包含了他在一年内遇到的所有面试题以及答案,甚至包括面试中的细节对话以及语录,可谓是细节到极致,甚至简历优化和怎么投简历更容易得到面试机会也包括在内!也包括教你怎么去获得一些大厂,比如阿里,腾讯的内推名额!某位名人说过成功是靠99%的汗水和1%的机遇得到的,而你想获得那1%的机遇你首先就得付出99%的汗水!你只有朝着你的目标一步一步坚持不懈的走下去你才能有机会获得成功!成功只会留给那些有准备的人!

2401_84003839的博客 778

90%的Java程序员都踩过的内存坑,你还敢说自己稳了吗?

别急!今天这篇就带你✍大家好,我是默语,别名默语博主,擅长的技术领域包括Java、运维和人工智能。我的技术背景扎实,涵盖了从后端开发到前端框架的各个方面,特别是在Java 性能优化、多线程编程、算法优化等领域有深厚造诣。目前,我活跃在优快云、掘金、阿里云和 51CTO等平台,全网拥有超过15万的粉丝,总阅读量超过1400 万。统一 IP 名称为默语或者默语博主。

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 1万+

Java面试-CMS 垃圾回收器的工作流程与缺点

《Java面试200问:深入解析CMS垃圾回收器》 本文系统讲解了CMS垃圾回收器的核心原理与应用场景。通过商场保洁员的生动比喻,形象阐释了CMS"并发标记-清除"的工作机制:初始标记(STW)→并发标记→重新标记(STW)→并发清除四大阶段。重点分析了CMS的三大缺点:内存碎片问题、高CPU资源消耗及并发模式失败风险,并提供了详细的调优方案,包括触发阈值设置、并行度优化等参数配置建议。文章还包含完整的流程图解和面试高频问题解析,帮助开发者深入理解这一经典老年代回收器的特性与适用场景。

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

大专刚毕业的我都可以拿到大厂offer,你还去摸鱼嘛

,给大家整理了今年来最经典的面试真题100道,每个题目都有详细的解答,收集了java基础、RabbitMQ,微服务、MySQL数据库、Java并发、JVM,Redis、设计模式,Spring / Spring MVC,等专题的经典面试真题,和详细分析。 数据库篇 事务四大特性(ACID)原子性、一致性、隔离性、持久性? 事务的并发?事务隔离级别,每个级别会引发什么问题,MySQL默认是哪个级别? MySQL常见的三种存储引擎(InnoDB、MyISAM、MEMORY)的区别? MySQL的MyIS

weixin_58610844的博客 112

上班摸鱼在群里吹牛B,逮到一个华为10年老Java开发,聊过之后收益良多...

接私活 对程序员这个圈子来说是一个既公开又隐私的话题,不说全部,应该大多数程序员都有过想要接私活的想法,当然,也有部分得道成仙的不主张接私活。但是很少有人在公开场合讨论私活的问题,似乎都在避嫌。就跟有人下班后跑滴滴一样,程序员私有时间接点活挣点钱不也很正常么,不过不要在上班时间就行,就跟你上班期间出去跑滴滴一样。 但是我是不建议接私活的,接私活会浪费自己在一大部分的精力,就算不接私活,利用好工作后的八小时也能比别人强,月薪也绝对不会比那些接私活的少。 把有限的时间花在提升自己的能力上,技术深度,技术广度

qq_42986622的博客 812

【Fifty Project - D9】

学习了几个老垃圾收集器:Serial,SerialOld, ParNew, ParallalScarenge, Parallel Old, CMS。今天的每日一题又是个Hard,吓死人的Hard,直接给我干懵逼了~ 今天是没完成计划的飞舞。复制,新生代垃圾收集器,单线程,全程需要STW, 老年代配合SerialOld使用。优点是:实现简单,单线程无线程切换开销,在桌面应用等内存不大的应用中有着不错的表现。复制,新生代垃圾收集器,多线程,老年代配合SerialOld使用。多线程,复制,新生代收集器。

qq_44267363的博客 314

java虚拟机概述

导读:我们写了一行Java语言的代码,那么这行代码执行的时候到底发生了什么事情,就需要我们对Java虚拟机以及背后的运行机制有深入的理解,本文只是作为复习资料做一个笼统的介绍。学习JVM需要一些前置知识,这些知识包括计算机组成原理、操作系统;如果想深入理解的理解JVM,可以看周志明的《深入理解JAVA虚拟机》以及《Java虚拟机规范》、《Java语言规范》;本文仍旧希望能说清楚JVM内在演变逻辑。...

weixin_47267435的博客 52
上一篇: 摸鱼JVM - 执行引擎
下一篇: 警惕, 差点着了副业骗局的道
码哥说
博客等级 码龄8年 5645粉丝 172原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值