JVM学习笔记1.0

告别Quartus II的漫长等待:用VSCode+iverilog+GTKWave搭建你的轻量级Verilog仿真环境(2024保姆级教程) 本文详细介绍了如何利用VSCode、iverilog和GTKWave构建高效的Verilog/SystemVerilog开发环境,替代传统的Quartus II和ModelSim工具。通过2024年最新的保姆级教程,帮助开发者实现秒级启动、低资源消耗的轻量级仿真环境,显著提升数字电路设计的开发效率和调试体验。 阅读详情

1.Java 虚拟机需要将字节码翻译成机器码

    在 HotSpot 里面,有两种形式:第一种是解释执行,即逐条将字节码翻译成机器码并执行;第二种是即时编译(Just-In-Time compilation,JIT),即将一个方法中包含的所有字节码编译成机器码后再执行。前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。HotSpot默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。

2.HotSpot的即时编译器

    HotSpot 内置了多个即时编译器:C1、C2 和 Graal。Graal 是 Java 10 正式引入的实验性即时编译器。之所以引入多个即时编译器,是为了在编译时间和生成代码的执行效率之间进行取舍。
    C1 又叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,因此编译时间较短。C2 又叫做 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂,因此编译时间较长,但同时生成代码的执行效率较高。
    从 Java 7 开始,HotSpot 默认采用分层编译的方式:热点方法首先会被 C1 编译,而后热点方法中的热点会进一步被 C2 编译。为了不干扰应用的正常运行,HotSpot 的即时编译是放在额外的编译线程中进行的。HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例配置给 C1 及 C2 编译器。在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成后的机器码会在下次调用该方法时启用,以替换原本的解释执行。

3.类的初始化

类的初始化何时会被触发呢?JVM 规范枚举了下述多种触发情况:
    1.当虚拟机启动时,初始化用户指定的主类;
    2.当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类;
    3.当遇到调用静态方法的指令时,初始化该静态方法所在的类;当遇到访问静态字段的指令时,初始化该静态字段所在的类;
    4.子类的初始化会触发父类的初始化;如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化;
    5.使用反射 API 对某个类进行反射调用时,初始化这个类;当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。

4.异常处理

1.异常处理的两大组成要素是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。

    抛出异常可分为显式和隐式两种。显式抛异常的主体是应用程序,它指的是在程序中使用“throw”关键字,手动将异常实例抛出。
    隐式抛异常的主体则是 Java 虚拟机,它指的是 Java 虚拟机在执行过程中,碰到无法继续执行的异常状态,自动抛出异常。举例来说,Java 虚拟机在执行读取数组操作时,发现输入的索引值是负数,故而抛出数组索引越界异常(ArrayIndexOutOfBoundsException)。

2.捕获异常则涉及了如下三种代码块:

    try 代码块:用来标记需要进行异常监控的代码。

    catch 代码块:跟在 try 代码块之后,用来捕获在 try 代码块中触发的某种指定类型的异常。除了声明所捕获异常的类型之外,catch 代码块还定义了针对该异常类型的异常处理器。在 Java 中,try 代码块后面可以跟着多个 catch 代码块,来捕获不同类型的异常。Java 虚拟机会从上至下匹配异常处理器。因此,前面的 catch 代码块所捕获的异常类型不能覆盖后边的,否则编译器会报错。

    finally 代码块:跟在 try 代码块和 catch 代码块之后,用来声明一段必定运行的代码。它的设计初衷是为了避免跳过某些关键的清理代码,例如关闭已打开的系统资源。

3.在 Java 语言规范中,所有异常都是 Throwable 类或者其子类的实例。Throwable 有两大直接子类。第一个是 Error,涵盖程序不应捕获的异常。当程序触发 Error 时,它的执行状态已经无法恢复,需要中止线程甚至是中止虚拟机。第二子类则是 Exception,涵盖程序可能需要捕获并且处理的异常。

4.RuntimeException 和 Error 属于 Java 里的非检查异常(unchecked exception)。其他异常则属于检查异常(checked exception)。在 Java 语法中,所有的检查异常都需要程序显式地捕获,或者在方法声明中用 throws 关键字标注。通常情况下,程序中自定义的异常应为检查异常,以便最大化利用 Java 编译器的编译时检查。

5.Java 字节码中,每个方法对应一个异常表。当程序触发异常时,Java 虚拟机将查找异常表,并依此决定需要将控制流转移至哪个异常处理器之中。Java 代码中的 catch 代码块和 finally 代码块都会生成异常表条目。

5.反射

    Method.invoke 实际上委派给 MethodAccessor 来处理。MethodAccessor 是一个接口,它有两个已有的具体实现:一个通过本地方法来实现反射调用,另一个则使用了委派模式。
    Java 的反射调用机制还设立了另一种动态生成字节码的实现(下称动态实现),直接使用 invoke 指令来调用目标方法。之所以采用委派实现,便是为了能够在本地实现以及动态实现中切换。
    动态实现和本地实现相比,其运行效率要更快。这是因为动态实现无需经过 Java 到 C++ 再到 Java 的切换,但由于生成字节码十分耗时,仅调用一次的话,反而是本地实现更快。
    考虑到许多反射调用仅会执行一次,Java 虚拟机设置了一个阈值 15(可以通过 -Dsun.reflect.inflationThreshold= 来调整),当某个反射调用的调用次数在 15 之下时,采用本地实现;当达到 15 时,便开始动态生成字节码,并将委派实现的委派对象切换至动态实现,这个过程称之为 Inflation。
    方法的反射调用会带来不少性能开销,原因主要有三个:变长参数方法导致的 Object 数组,基本类型的自动装箱、拆箱,还有最重要的方法内联。

6.Java 虚拟机中 synchronized 关键字的实现

    Java 虚拟机中 synchronized 关键字的实现,按照代价由高至低可分为重量级锁、轻量级锁和偏向锁三种。
    重量级锁会阻塞、唤醒请求加锁的线程。它针对的是多个线程同时竞争同一把锁的情况。为了尽量避免昂贵的线程阻塞、唤醒操作,Java 虚拟机会在线程进入阻塞状态之前,以及被唤醒后竞争不到锁的情况下,进入自旋状态,在处理器上空跑并且轮询锁是否被释放。如果此时锁恰好被释放了,那么当前线程便无须进入阻塞状态,而是直接获得这把锁。Java 虚拟机采取了自适应自旋(根据以往自旋等待时是否能够获得锁,来动态调整自旋的时间(循环数目)),来避免线程在面对非常小的 synchronized 代码块时,仍会被阻塞、唤醒的情况。
    轻量级锁采用 CAS 操作,将锁对象的标记字段替换为一个指针,指向当前线程栈上的一块空间,存储着锁对象原本的标记字段。它针对的是多个线程在不同时间段申请同一把锁的情况。
    偏向锁只会在第一次请求时采用 CAS 操作,在锁对象的标记字段中记录下当前线程的地址。在之后的运行过程中,持有该偏向锁的线程的加锁操作将直接返回。它针对的是锁仅会被同一线程持有的情况。

7.即时编译

    即时编译是一项用来提升应用程序运行效率的技术。通常而言,代码会先被 Java 虚拟机解释执行,之后反复执行的热点代码则会被即时编译成为机器码,直接运行在底层硬件之上。
    对于执行时间较短的,或者对启动性能有要求的程序,采用编译效率较快的 C1;。对于执行时间较长的,或者对峰值性能有要求的程序,采用生成代码执行效率较快的 C2。
    Java 虚拟机是根据方法的调用次数以及循环回边的执行次数(在字节码中,可以简化理解为往回跳转的指令)来触发即时编译的。

8.方法内联

    方法内联指的是:在编译过程中遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。
    在 C2 编译器中,方法内联是在解析字节码的过程中完成的。每当碰到方法调用字节码时,C2 将决定是否需要内联该方法调用。如果需要内联,则开始解析目标方法的字节码。
    方法内联能够触发更多的优化。通常而言,内联越多,生成代码的执行效率越高。然而,对于即时编译器来说,内联越多,编译时间也就越长,而程序达到峰值性能的时刻也将被推迟。此外,内联越多也将导致生成的机器码越长。在 Java 虚拟机里,编译生成的机器码会被部署到 Code Cache 之中。这个 Code Cache 是有大小限制的(由 Java 虚拟机参数 -XX:ReservedCodeCacheSize 控制)。这就意味着,生成的机器码越长,越容易填满 Code Cache,从而出现 Code Cache 已满,即时编译已被关闭的警告信息(CodeCache is full. Compiler has been disabled)。因此,即时编译器不会无限制地进行方法内联。

    内联规则:

  • 由 -XX:CompileCommand 中的 inline 指令指定的方法,以及由 @ForceInline 注解的方法(仅限于 JDK 内部方法),会被强制内联。
  • 如果调用字节码对应的符号引用未被解析、目标方法所在的类未被初始化,或者目标方法是 native 方法,都将导致方法调用无法内联。
  • C2 不支持内联超过 9 层的调用(可以通过虚拟机参数 -XX:MaxInlineLevel 调整),以及 1 层的直接递归调用(可以通过虚拟机参数 -XX:MaxRecursiveInlineLevel 调整)。

    对于需要动态绑定的虚方法调用来说,即时编译器则需要先对虚方法调用进行去虚化(devirtualize),即转换为一个或多个直接调用,然后才能进行方法内联。

  • 完全去虚化通过类型推导或者类层次分析,将虚方法调用转换为直接调用。它的关键在于证明虚方法调用的目标方法是唯一的。
  • 条件去虚化通过向代码中增添类型比较,将虚方法调用转换为一个个的类型测试以及对应该类型的直接调用。它将借助 Java 虚拟机所收集的类型 Profile。

9.JNI

    Java 虚拟机会将所有 JNI 函数的函数指针聚合到一个名为JNIEnv的数据结构之中。这是一个线程私有的数据结构。Java 虚拟机会为每个线程创建一个JNIEnv,并规定 C 代码不能将当前线程的JNIEnv共享给其他线程,否则 JNI 函数的正确性将无法保证。
    JNI 中的引用可分为局部引用和全局引用。这两者都可以阻止垃圾回收器回收被引用的 Java 对象。不同的是,局部引用在 native 方法调用返回之后便会失效。传入参数以及大部分 JNI API 函数的返回值都属于局部引用。

10元注解

  • @Target注解
    Target注解的作用是:描述注解的使用范围(即:被修饰的注解可以用在什么地方) 。
  • @Retention注解
    Reteniton注解的作用是:描述注解保留的时间范围(即:被描述的注解在它所修饰的类中可以被保留到何时) 。
  • @Documented注解
    Documented注解的作用是:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。
  • @Inherited注解
    Inherited注解的作用是:使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解)。
【雷达】一维和二维自适应波束形成(DBF))DBF附matlab代码 1 简介 数字波束形成技术是天线波束形成原理与数字信号处理技术相结合的产物,其广泛应用于阵列信号处理领域.由于电磁工作环境的恶化和大量射频干扰的存在,在极低的信干噪比(SINR)条件下进行目标检测和信息提取十分困难.对于阵列系统,往往采用自适应数字波束形成(ADBF)技术,来抑制强干扰和方向性干扰对有用信号的影响.介绍了数字波束形成器的基本原理及其DSP的实现结构.​ 2 完整代码 clc;clear all;close all;%%%%%%%%%%%%%%%%%一维DBF%%%%%%%%%%%%% 阅读详情

相关推荐

【RK3588开发记录】超详细的RK3588修改debug串口波特率为115200

修改RK3588的debug串口为115200

Crazydrams的博客 4805

JVM内部机制揭秘:从字节码到机器指令的旅程

jvm就是java虚拟机,我们都知道,程序员编写的代码都是.java文件,这是高级语言,电脑并不能识别,电脑只能识别机器语言,也就是01代码,那么我们编写的.java文件是怎末变为能被电脑所识别的呢,这就要用到jvm了。

2301_79918813的博客 1445

【DIY】使用STM32及PID算法实现一个磁悬浮玩具

今天教大家来做一个磁悬浮玩具。

小白白学电子 1万+

HotSpot JVM 为啥要叫做 HotSpot JVM?

第二条执行路径,指的是编译对象非常简单的情况下,如getter和setter,虚拟机认为通过C1编译或通过C2编译并无区别,就会在3层编译后,直接由C1编译且不插入profiling代码(level 1)。否则,不用关系 织入了啥,了解这个思想就行。与解释执行相反,JVM加载字节码的时候,直接将字节码转换为机器码,在执行方法调用时直接执行机器码,不需要做翻译工作,这样的过程叫。第四条执行路径,指的是C2繁忙时,先由2层的C1编译再由3层的C1编译,这样可以减少方法在3层的执行时间,最终再交给C2执行。

harmful_sheep的博客 2042

中兴畅行60 ZTE 7552N 深度改造指南:从解锁BL到Magisk Root与IMEI硬改全流程

本文详细介绍了中兴畅行60(ZTE 7552N)的深度改造全流程,包括解锁BL、刷入Magisk获取Root权限以及IMEI硬改等关键步骤。通过专业的操作指南和实用技巧,帮助用户安全完成设备改造,同时提醒注意法律风险和技术难点。

weixin_33670786的博客 1899

Diffix3D+复现

上下载模型,将其放在一个目录中,并将目录名填在demo代码中from_pretrained的cache_dir参数里。目录结构应该是"<PATH>/nvidia/difix/…给的requirements文件中pytorch和xformers的版本没有指定,这里测试过以下版本,可以成功运行。将readme中的demo代码新建一个python脚本复制进去,然后将脚本放在src目录中运行。如果遇到网络问题无法加载huggingface上的预训练模型,可以手动从。如果出现,以下错误重新。

NeverMakeIt的博客 1087

1.1.2 Java @ForceInline 注解用法

本文作为Disruptor专栏中第1.1.2内容先来看看原文: 如果需要HotSpot VM的方法或构造器不需要使用标准指令排列处理时,可以使用此注解让其强制排列。 这个注解不能被滥用,它合理的用法是用来将其绑定到HotSpot VM的指定的方法或构造器中,用来提供一种排列策略。不能依赖该注解去避免VM的正常指令排列策略,在HotSpot VM中的少数情况下,它只能作为临时的应对方法,直到指令排列情况改善。这个注解仅对通过boot loader加载的类中的方法和构造器有影响,其他

一瓶绿茶三元钱 1288

使用 MATLAB/Simulink 来构建一个基于多能互补的微电网储能系统模型

【摘要】本文详细介绍了基于MATLAB/Simulink的多能互补微电网储能系统建模方法。教程涵盖光伏发电、风力发电、电池储能和负荷模块的搭建,重点讲解了能量管理系统(EMS)的调度策略实现。通过设置传感器监测关键参数,并采用固定步长离散求解器进行仿真,分析了系统在动态工况下的响应特性,包括发电-负荷平衡、储能状态变化及系统稳定性等指标。该建模方法为多能互补微电网的设计与优化提供了有效工具,对提升可再生能源利用效率具有实践指导意义。

MHD0815的博客 191

JVM——方法内联

JVM——方法内联:编译器优化的核心技术

从知识输入到知识输出 1302

【音视频 ffmpeg 学习】 RTMP推流 mp4文件

3.当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)。1.RTMP(实时消息传输协议)是Adobe 公司开发的一个基于TCP的应用层协议。2.RTMP协议中基本的数据单元称为消息(Message)。下载地址:http://nginx.org/download。下载 rtmp模块 到nginx 模块下。安装nginx 和 rtmp模块。(1). linux 环境准备。下载nginx安装包。使用 vcl 播放流。

weixin_45397344的博客 2276

OpenClaw简介--windows系统安装OpenClaw

在windows安装OpenClaw实现代替人工操作。步骤流程详细,图文并茂。

直到世界的尽头 5352

Java内联函数:提升性能的秘密武器,你掌握了吗?

你是否曾经在编写Java代码时,遇到过性能瓶颈的问题?是否曾经为了提高程序的运行效率,而苦苦寻找解决方案?今天,我要和你分享一个可能被你忽视的性能优化技巧——Java内联函数。

Q2024107的博客 614

Keras神经网络可视化模块keras.utils.visualize_util的安装配置方法

本文介绍了如何安装和配置keras.utils.visualize_util模块,并提供了一个简单的示例演示如何使用该模块来可视化神经网络的结构。在上述代码中,我们首先定义了一个简单的神经网络模型,该模型具有一个输入层、一个隐藏层和一个输出层,其中隐藏层具有512个神经元,输出层具有10个神经元。运行上述代码后,我们将在当前工作目录下找到一个名为model.png的文件,它显示了神经网络的结构图。这种方式有效地展示了整个过程,让我们能够更好地理解神经网络的结构,方便对其进行改进和调试。

. 892

JVM学习笔记21 java 工具

bilibili-JVM学习笔记21 java 工具 The Java Virtual Machine Specification - Java SE 8 Edition JVM学习笔记18 字节码知识总结 JVM学习笔记19 JVM内存空间 JVM学习笔记20 jvisualvm 基于 java 1.8.0 jmap与jstat工具实战分析 67 ➜ ~ jmap -h Usage: jmap [option] <pid> (to connect to running

晨猫 259

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JVM学习笔记(1)-JVM总体篇

目录 0 前言 1 Java体系描述 1.1 Java体系构成 1.2 Java平台描述 2 JVM体系描述 2.1 JVM基本概念 2.2 ​​​​​​​JVM运行原理 3 示例 参考 0 前言      最近买了周志明的《深入理解Java虚拟机 JVM高级特性与最佳实践 》,结合网上的相关文章资料,尝试做一套JVM学习笔记,也算整理和巩固。相关引用文章,已罗列在参考篇中,...

wingsing2010的专栏 4700

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

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

JVM学习笔记1

主要有五个阶段:(下面会重点讲解前三个阶段)

kwert666的博客 1648

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

JVM基础篇学习笔记

JVM是Java虚拟机的缩写,本质上是运行在计算机上面的程序,作用是运行Java字节码文件。Tomcat使用了自定义类加载器来实现应用之间类的隔离,每一个应用会有一个独立的类加载器加载对于的类。ClassLoader的四个重要方法:// 每一个类加载器都会检查这个类有没有被加载过Class

无奇不有 不置可否的博客 1736

JVM学习笔记

类加载学习笔记步骤LoadingLinkingVerificationPrearationResolutionInitializing 步骤 loading linking verification prearation resolution initializing Loading 将class文件装载到内存:将文件放入内存中,在生成一个class对象对应这块内存,1.8之后class对像在matespace中。 类加载器使用双亲委派机制,主要是为了安全问题。 Linking Verificat

qq_39085029的博客 1443

记录一个JVM crash(jdk1.8.0_31版本bug)

现象 ider更新代码使用jrebel热部署代码。tomcat崩溃,并报以下错误: # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000075744686, pid=18436, tid=995...

雄的博客 1728

JVM 基础知识学习笔记

JVM 一个运行在计算机上的程序,它的职责是运行 Java 字节码文件。

Gjw_java的博客 1155

配置jvm堆最大内存&eden区与s0或者s1区域比例

配置堆内存大小,其实比较简单,你们以后做JVM调优,主要是围绕着哪个内存区域,都是围绕着堆内存的,像栈每次 用完之后都会自动释放的,还有方法区,但是方法区你不用考虑,因为它如果满的情况下,垃圾回收会自动去回收,但是主要还是围绕 堆内存的,我们怎么去配置堆内存大小,在这里给你们介绍几个方法 package com.learn.test; /** * 我们怎么去配置堆内存大小 * 打印...

Leon_Jinhai_Sun的博客 5671

1.0、JVM概览

Java 虚拟机简介 JVM的位置 JVM 的整体结构 Java 代码执行流程 JVM 架构模型 JVM 声明周期 启动 执行 退出 各类 JVM 的实现 SUN Classic VM Exact VM HotSpot VM JRockit IBM J9 KVM & CDC/CLDC Hotspot Azul VM & BEA Liquid VM Apache Harmony Microsoft JVM TaobaoJVM Dalvik VM Graal VM Java.

weixin_43658899的博客 226

【1】JVM1-10

目录 知识点1:栈帧的产生和销毁,什么时候出OOM错误? 知识点2:JVM优化 知识点3:什么情况下会导致YGC,怎么控制伊甸园区的比例 知识点4:G1垃圾回收机制了解吗? 知识点5:获取JAVA对象占用的内存大小 知识点6:Java内存模型 知识点7:垃圾回收算法 知识点8:创建对象在堆中的存放,新生代、年老代用的算法 知识点9:永久代 知识点10:什么情况下栈溢出?堆溢出?...

19年的努力,并不是说说而已! 12万+

zabbix4.0监控JVM

Zabbix JVM

qq_26700739的博客 3241

java eden s0 s1_Jvm组成以及调优

Jvm的内存由三部分组成Eden,S0,S1,Old以及Metaspace(JDK1.8之前的Perm区)五部分组成;(图片摘自VisualVM的Visual GC插件)抽象为三代:新生代(Eden,S0,S1);老年代(old)以及持久代(Metaspace/Perm);java -server -Xms100m -Xmx2g -XX:NewSize=100m-XX:SurvivorRatio...

weixin_35727143的博客 656

Java学习笔记之JVM篇

Java学习笔记之JVM篇前言问:什么是JVM?问:JRE/JDK/JVM是什么关系?判断对象是否存活的算法问:如何回收对象垃圾收集算法(4种) 前言 这是JVM学习笔记,内容主要来自 周志明编写的《深入理解Java虚拟机 JVM高级特性与最佳实践》(第2版)一书,相当于是此书的读书笔记,还有一些内容引用自公众号内容 问:什么是JVM? 答:JVM是Java Virtual Machine(Jav...

qq_34882796的博客 872
上一篇: JVM学习笔记2.0
下一篇: Oracle:ROWNUM介绍和分页使用
过河的小卒子
博客等级 码龄10年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值