Java领域JVM的堆内存使用率监控

Java领域JVM的堆内存使用率监控

关键词:Java、JVM、堆内存使用率、监控、性能优化

摘要:本文围绕Java领域中JVM堆内存使用率监控展开深入探讨。首先介绍了监控JVM堆内存使用率的背景、目的和适用读者群体,接着阐述了JVM堆内存的核心概念、架构及工作原理,详细讲解了用于监控的核心算法和具体操作步骤,并给出相应的Python代码示例。同时,还引入了相关的数学模型和公式以加深理解。通过项目实战,展示了如何搭建开发环境、实现监控代码并进行解读。此外,探讨了堆内存使用率监控在实际中的应用场景,推荐了学习资源、开发工具框架和相关论文著作。最后总结了未来发展趋势与挑战,提供常见问题解答和扩展阅读参考资料,旨在帮助开发者全面掌握JVM堆内存使用率监控的技术,提升Java应用的性能和稳定性。

1. 背景介绍

1.1 目的和范围

在Java应用开发中,JVM(Java Virtual Machine)的堆内存管理至关重要。堆内存是Java对象存储的主要区域,其使用率直接影响着应用的性能和稳定性。监控JVM堆内存使用率的目的在于及时发现内存泄漏、内存溢出等问题,优化内存使用,提高应用的响应速度和吞吐量。本文的范围涵盖了JVM堆内存使用率监控的原理、方法、工具以及实际应用,帮助开发者全面了解和掌握这一关键技术。

1.2 预期读者

本文主要面向Java开发者、系统管理员和对JVM性能优化感兴趣的技术人员。无论是初学者希望了解JVM堆内存的基本概念,还是有经验的开发者寻求更高级的监控和优化方法,都能从本文中获得有价值的信息。

1.3 文档结构概述

本文将按照以下结构展开:首先介绍JVM堆内存的核心概念和联系,包括其架构和工作原理;接着讲解用于监控堆内存使用率的核心算法和具体操作步骤,并给出Python代码示例;然后引入相关的数学模型和公式进行详细讲解;通过项目实战展示如何搭建开发环境、实现监控代码并进行解读;探讨堆内存使用率监控在实际中的应用场景;推荐学习资源、开发工具框架和相关论文著作;最后总结未来发展趋势与挑战,提供常见问题解答和扩展阅读参考资料。

1.4 术语表

1.4.1 核心术语定义
  • JVM(Java Virtual Machine):Java虚拟机,是Java程序的运行环境,负责加载字节码文件、执行Java程序,并管理内存等资源。
  • 堆内存(Heap Memory):JVM中用于存储Java对象的区域,是Java程序运行时的主要内存区域之一。
  • 堆内存使用率(Heap Memory Usage Ratio):指当前堆内存中已使用的内存占总堆内存的比例,用于衡量堆内存的使用情况。
  • 内存泄漏(Memory Leak):指程序在运行过程中,由于某些原因导致一些对象无法被垃圾回收器回收,从而造成内存不断占用,最终导致内存溢出。
  • 内存溢出(OutOfMemoryError):指程序在申请内存时,没有足够的内存空间供其使用,从而抛出的异常。
1.4.2 相关概念解释
  • 垃圾回收(Garbage Collection):JVM自动回收不再使用的对象所占用的内存空间的过程,以保证堆内存的有效利用。
  • 分代收集算法(Generational Collection Algorithm):一种基于对象存活时间的垃圾回收算法,将堆内存分为新生代、老年代和永久代(Java 8及以后为元空间),不同代采用不同的垃圾回收策略。
  • 堆内存分区:JVM堆内存通常分为新生代(Eden区、Survivor区)和老年代,不同区域的对象具有不同的生命周期和垃圾回收特点。
1.4.3 缩略词列表
  • GC(Garbage Collection):垃圾回收
  • OOM(OutOfMemoryError):内存溢出
  • JMX(Java Management Extensions):Java管理扩展,用于管理和监控Java应用程序

2. 核心概念与联系

2.1 JVM堆内存架构

JVM堆内存是Java对象存储的主要区域,其架构通常分为新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,Java 8及以后为元空间,Metaspace)。以下是JVM堆内存架构的示意图:

堆内存 Heap Memory
新生代 Young Generation
老年代 Old Generation
Eden区 Eden Space
Survivor区 Survivor Space
S0区 Survivor 0
S1区 Survivor 1

2.2 各区域功能和工作原理

2.2.1 新生代

新生代是新创建的对象首先分配的区域,它又分为Eden区和Survivor区。当一个对象被创建时,首先会被分配到Eden区。当Eden区满时,会触发一次Minor GC(新生代垃圾回收),将存活的对象移动到Survivor区。Survivor区有两个,分别为S0和S1,每次Minor GC后,存活的对象会在S0和S1之间来回移动,经过一定次数的移动后,如果对象仍然存活,则会被移动到老年代。

2.2.2 老年代

老年代用于存储生命周期较长的对象,如缓存对象、静态对象等。当新生代的对象经过多次Minor GC后仍然存活,或者大对象直接分配到老年代时,对象会进入老年代。当老年代空间不足时,会触发一次Full GC(全量垃圾回收),对整个堆内存进行垃圾回收。

2.2.3 永久代(元空间)

永久代(Java 8及以后为元空间)主要用于存储类的元数据信息,如类的定义、方法、字段等。在Java 8之前,永久代是堆内存的一部分,有固定的大小限制;而在Java 8及以后,永久代被元空间取代,元空间使用本地内存,不再受堆内存大小的限制。

2.3 堆内存使用率的计算

堆内存使用率是指当前堆内存中已使用的内存占总堆内存的比例,计算公式如下:

堆内存使用率 = 已使用堆内存 总堆内存 × 100 % 堆内存使用率 = \frac{已使用堆内存}{总堆内存} \times 100\% 堆内存使用率=总堆内存已使用堆内存×100%

通过监控堆内存使用率,可以及时发现内存泄漏和内存溢出等问题,为性能优化提供依据。

3. 核心算法原理 & 具体操作步骤

3.1 核心算法原理

监控JVM堆内存使用率的核心算法是通过获取JVM的内存管理信息,计算已使用堆内存和总堆内存的大小,然后根据上述公式计算堆内存使用率。在Java中,可以使用java.lang.management包中的MemoryMXBean接口来获取堆内存的使用情况。以下是一个简单的Java代码示例:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;

public class HeapMemoryMonitor {
    public static void main(String[] args) {
        // 获取MemoryMXBean实例
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        // 获取堆内存使用情况
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();

        // 获取已使用堆内存
        long usedHeapMemory = heapMemoryUsage.getUsed();
        // 获取总堆内存
        long totalHeapMemory = heapMemoryUsage.getMax();

        // 计算堆内存使用率
        double heapMemoryUsageRatio = (double) usedHeapMemory / totalHeapMemory * 100;

        System.out.printf("堆内存使用率: %.2f%%\n", heapMemoryUsageRatio);
    }
}

3.2 具体操作步骤

3.2.1 获取JVM的内存管理信息

通过ManagementFactory.getMemoryMXBean()方法获取MemoryMXBean实例,该实例提供了获取堆内存和非堆内存使用情况的方法。

3.2.2 获取堆内存使用情况

调用MemoryMXBean实例的getHeapMemoryUsage()方法,返回一个MemoryUsage对象,该对象包含了堆内存的使用信息,如已使用内存、总内存、最大内存等。

3.2.3 计算堆内存使用率

根据MemoryUsage对象获取已使用堆内存和总堆内存的大小,然后根据上述公式计算堆内存使用率。

3.2.4 输出结果

将计算得到的堆内存使用率输出,以便进行监控和分析。

3.3 Python代码示例

除了Java代码,还可以使用Python通过JMX(Java Management Extensions)来监控JVM堆内存使用率。以下是一个使用py4j库实现的Python代码示例:

from py4j.java_gateway import JavaGateway

# 连接到JVM
gateway = JavaGateway()

# 获取MemoryMXBean实例
memory_mx_bean = gateway.jvm.java.lang.management.ManagementFactory.getMemoryMXBean()

# 获取堆内存使用情况
heap_memory_usage = memory_mx_bean.getHeapMemoryUsage()

# 获取已使用堆内存
used_heap_memory = heap_memory_usage.getUsed()
# 获取总堆内存
total_heap_memory = heap_memory_usage.getMax()

# 计算堆内存使用率
heap_memory_usage_ratio = used_heap_memory / total_heap_memory * 100

print(f"堆内存使用率: {heap_memory_usage_ratio:.2f}%")

# 关闭连接
gateway.close()

在上述代码中,首先使用py4j库连接到JVM,然后通过JVM的ManagementFactory类获取MemoryMXBean实例,进而获取堆内存使用情况并计算堆内存使用率。最后关闭连接。

4. 数学模型和公式 & 详细讲解 & 举例说明

4.1 堆内存使用率计算公式

在前面已经提到,堆内存使用率的计算公式为:

堆内存使用率 = 已使用堆内存 总堆内存 × 100 % 堆内存使用率 = \frac{已使用堆内存}{总堆内存} \times 100\% 堆内存使用率=总堆内存已使用堆内存×100%

其中,已使用堆内存是指当前堆内存中已经被对象占用的内存大小,总堆内存是指JVM为堆内存分配的最大内存大小。

4.2 详细讲解

4.2.1 已使用堆内存

已使用堆内存可以通过MemoryUsage对象的getUsed()方法获取。在JVM中,已使用堆内存会随着对象的创建和销毁而动态变化。当创建新对象时,已使用堆内存会增加;当垃圾回收器回收对象时,已使用堆内存会减少。

4.2.2 总堆内存

总堆内存可以通过MemoryUsage对象的getMax()方法获取。总堆内存的大小可以通过JVM启动参数进行配置,如-Xmx参数用于指定堆内存的最大大小。

4.2.3 堆内存使用率的意义

堆内存使用率是衡量堆内存使用情况的重要指标。如果堆内存使用率过高,可能会导致内存溢出异常;如果堆内存使用率过低,可能表示内存资源没有得到充分利用。因此,通过监控堆内存使用率,可以及时发现内存问题并进行优化。

4.3 举例说明

假设JVM的总堆内存大小为1024MB,当前已使用堆内存为512MB,则堆内存使用率为:

堆内存使用率 = 512 1024 × 100 % = 50 % 堆内存使用率 = \frac{512}{1024} \times 100\% = 50\% 堆内存使用率=1024512×100%=50%

这表示当前堆内存已经使用了一半,还有一半的可用空间。如果堆内存使用率持续上升,接近或达到100%,则需要及时检查是否存在内存泄漏或大对象分配等问题。

5. 项目实战:代码实际案例和详细解释说明

5.1 开发环境搭建

5.1.1 Java环境

确保已经安装了Java开发环境(JDK),可以通过以下命令检查Java版本:

java -version

如果没有安装JDK,可以从Oracle官方网站或OpenJDK官网下载并安装。

5.1.2 Python环境

确保已经安装了Python环境,可以通过以下命令检查Python版本:

python --version

如果没有安装Python,可以从Python官方网站下载并安装。

5.1.3 相关库安装

如果使用Python通过JMX监控JVM堆内存使用率,需要安装py4j库,可以使用以下命令进行安装:

pip install py4j

5.2 源代码详细实现和代码解读

5.2.1 Java代码实现

以下是一个完整的Java代码示例,用于定时监控JVM堆内存使用率:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.Timer;
import java.util.TimerTask;

public class HeapMemoryMonitor {
    public static void main(String[] args) {
        // 创建一个定时器
        Timer timer = new Timer();

        // 定义定时任务
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                // 获取MemoryMXBean实例
                MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
                // 获取堆内存使用情况
                MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();

                // 获取已使用堆内存
                long usedHeapMemory = heapMemoryUsage.getUsed();
                // 获取总堆内存
                long totalHeapMemory = heapMemoryUsage.getMax();

                // 计算堆内存使用率
                double heapMemoryUsageRatio = (double) usedHeapMemory / totalHeapMemory * 100;

                System.out.printf("堆内存使用率: %.2f%%\n", heapMemoryUsageRatio);
            }
        };

        // 每隔5秒执行一次任务
        timer.schedule(task, 0, 5000);
    }
}
5.2.2 代码解读
  • 定时器的使用:使用java.util.Timerjava.util.TimerTask类实现定时任务,每隔5秒执行一次堆内存使用率的监控。
  • 获取堆内存使用情况:通过ManagementFactory.getMemoryMXBean()方法获取MemoryMXBean实例,然后调用getHeapMemoryUsage()方法获取堆内存使用情况。
  • 计算堆内存使用率:根据MemoryUsage对象获取已使用堆内存和总堆内存的大小,然后计算堆内存使用率。
  • 输出结果:将计算得到的堆内存使用率输出到控制台。
5.2.3 Python代码实现

以下是一个完整的Python代码示例,用于定时监控JVM堆内存使用率:

from py4j.java_gateway import JavaGateway
import time

def monitor_heap_memory():
    # 连接到JVM
    gateway = JavaGateway()

    while True:
        # 获取MemoryMXBean实例
        memory_mx_bean = gateway.jvm.java.lang.management.ManagementFactory.getMemoryMXBean()

        # 获取堆内存使用情况
        heap_memory_usage = memory_mx_bean.getHeapMemoryUsage()

        # 获取已使用堆内存
        used_heap_memory = heap_memory_usage.getUsed()
        # 获取总堆内存
        total_heap_memory = heap_memory_usage.getMax()

        # 计算堆内存使用率
        heap_memory_usage_ratio = used_heap_memory / total_heap_memory * 100

        print(f"堆内存使用率: {heap_memory_usage_ratio:.2f}%")

        # 每隔5秒监控一次
        time.sleep(5)

if __name__ == "__main__":
    monitor_heap_memory()
5.2.4 代码解读
  • 连接到JVM:使用py4j库的JavaGateway类连接到JVM。
  • 循环监控:使用while True循环不断监控堆内存使用率。
  • 获取堆内存使用情况:通过JVM的ManagementFactory类获取MemoryMXBean实例,进而获取堆内存使用情况。
  • 计算堆内存使用率:根据MemoryUsage对象获取已使用堆内存和总堆内存的大小,然后计算堆内存使用率。
  • 输出结果:将计算得到的堆内存使用率输出到控制台。
  • 定时监控:使用time.sleep(5)方法每隔5秒执行一次监控任务。

5.3 代码解读与分析

5.3.1 Java代码分析

Java代码使用了Java的标准库,通过ManagementFactoryMemoryMXBean接口获取堆内存使用情况,实现简单直接。使用TimerTimerTask类实现定时任务,适用于简单的定时监控场景。但需要注意的是,Timer类是单线程的,如果任务执行时间过长,可能会影响后续任务的执行。

5.3.2 Python代码分析

Python代码使用了py4j库通过JMX连接到JVM,实现了与Java代码相同的功能。使用while True循环和time.sleep()方法实现定时监控,简单易懂。但需要确保JVM和Python程序在同一台机器上运行,并且JVM开启了JMX远程访问功能。

6. 实际应用场景

6.1 生产环境监控

在生产环境中,监控JVM堆内存使用率可以及时发现内存泄漏、内存溢出等问题,避免应用程序因内存问题而崩溃。通过实时监控堆内存使用率,可以设置阈值,当堆内存使用率超过阈值时,及时发出警报,通知运维人员进行处理。

6.2 性能优化

通过监控JVM堆内存使用率,可以分析应用程序的内存使用情况,找出内存占用过高的原因,如大对象分配、对象生命周期过长等。根据分析结果,可以对代码进行优化,如减少大对象的创建、及时释放不再使用的对象等,从而提高应用程序的性能和稳定性。

6.3 容量规划

在进行系统容量规划时,监控JVM堆内存使用率可以帮助确定应用程序所需的堆内存大小。通过分析历史堆内存使用数据,可以预测应用程序在不同负载下的内存使用情况,从而合理分配堆内存资源,避免资源浪费或不足。

6.4 故障排查

当应用程序出现性能问题或崩溃时,监控JVM堆内存使用率可以提供重要的线索。通过查看堆内存使用率的变化趋势,可以判断是否是由于内存问题导致的故障。例如,如果堆内存使用率持续上升,可能存在内存泄漏;如果堆内存使用率突然下降,可能是发生了Full GC。

7. 工具和资源推荐

7.1 学习资源推荐

7.1.1 书籍推荐
  • 《深入理解Java虚拟机:JVM高级特性与最佳实践》:这本书详细介绍了JVM的内部原理、垃圾回收机制、内存管理等内容,是学习JVM的经典书籍。
  • 《Effective Java》:这本书介绍了Java编程的最佳实践和技巧,对于提高Java代码的质量和性能有很大帮助。
  • 《Java性能权威指南》:这本书深入探讨了Java应用程序的性能优化方法,包括JVM调优、代码优化、性能监控等方面。
7.1.2 在线课程
  • Coursera上的“Java Programming and Software Engineering Fundamentals”:该课程介绍了Java编程的基础知识和软件工程项目的实践经验。
  • Udemy上的“Java Performance Tuning Masterclass”:该课程专门讲解了Java性能调优的方法和技巧,包括JVM调优、垃圾回收优化等内容。
7.1.3 技术博客和网站
  • InfoQ:提供了大量关于Java技术和JVM性能优化的文章和资讯。
  • DZone:是一个技术社区,有很多关于Java和JVM的技术文章和经验分享。
  • Java官方文档:是学习Java和JVM的权威资料,包含了详细的API文档和技术指南。

7.2 开发工具框架推荐

7.2.1 IDE和编辑器
  • IntelliJ IDEA:是一款功能强大的Java集成开发环境,提供了丰富的代码编辑、调试、性能分析等功能。
  • Eclipse:是一款开源的Java集成开发环境,广泛应用于Java开发领域。
  • Visual Studio Code:是一款轻量级的代码编辑器,支持Java开发,通过安装相关插件可以实现代码编辑、调试等功能。
7.2.2 调试和性能分析工具
  • VisualVM:是一款免费的Java性能分析工具,提供了直观的图形界面,可用于监控JVM的内存使用情况、线程状态、垃圾回收等信息。
  • YourKit Java Profiler:是一款商业的Java性能分析工具,功能强大,可用于深入分析Java应用程序的性能瓶颈。
  • Java Mission Control:是Oracle提供的一款性能监控和诊断工具,可用于监控JVM的各种指标,如内存使用、CPU使用率等。
7.2.3 相关框架和库
  • Spring Boot:是一个用于快速开发Java应用程序的框架,提供了自动配置和嵌入式服务器等功能,简化了Java开发流程。
  • Hibernate:是一个Java持久化框架,用于实现对象关系映射(ORM),简化了数据库操作。
  • Apache Kafka:是一个分布式流处理平台,可用于构建高吞吐量、低延迟的实时数据处理系统。

7.3 相关论文著作推荐

7.3.1 经典论文
  • “The Garbage Collection Handbook: The Art of Automatic Memory Management”:这本书详细介绍了垃圾回收的原理、算法和实现,是垃圾回收领域的经典著作。
  • “Java Memory Management: Optimizing Java SE, EE, and ME Applications”:这本书介绍了Java内存管理的原理和优化方法,对于理解JVM内存管理有很大帮助。
7.3.2 最新研究成果
  • 可以关注ACM SIGPLAN、IEEE Transactions on Software Engineering等学术期刊和会议,获取关于JVM性能优化和内存管理的最新研究成果。
7.3.3 应用案例分析
  • 可以参考一些大型互联网公司的技术博客,如阿里巴巴、腾讯、字节跳动等,了解他们在JVM性能优化和内存管理方面的实践经验和应用案例。

8. 总结:未来发展趋势与挑战

8.1 未来发展趋势

8.1.1 智能化监控

随着人工智能和机器学习技术的发展,未来的JVM堆内存使用率监控将更加智能化。通过对大量历史数据的分析和学习,监控系统可以自动识别内存泄漏、内存溢出等问题的模式和特征,并提前发出预警。

8.1.2 云原生监控

随着云计算和容器技术的普及,越来越多的Java应用程序将运行在云环境中。未来的JVM堆内存使用率监控将更加注重云原生环境的支持,如与Kubernetes、Docker等容器编排工具的集成,实现对分布式应用程序的实时监控和管理。

8.1.3 多语言监控

随着微服务架构的流行,一个应用程序可能会由多种编程语言编写。未来的JVM堆内存使用率监控将不仅局限于Java应用程序,还将支持对其他编程语言的内存使用情况进行监控,实现跨语言的统一监控和管理。

8.2 挑战

8.2.1 数据处理和分析

随着监控数据的不断增加,如何高效地处理和分析这些数据是一个挑战。需要采用大数据处理和分析技术,如分布式计算、机器学习等,来提高数据处理和分析的效率和准确性。

8.2.2 兼容性和可扩展性

随着Java版本的不断更新和新技术的不断涌现,监控工具需要具备良好的兼容性和可扩展性,以支持新的Java特性和功能。同时,监控工具还需要能够与其他系统和工具进行集成,实现数据的共享和交互。

8.2.3 安全和隐私

在监控过程中,需要处理大量的敏感数据,如内存使用情况、对象信息等。如何保证这些数据的安全和隐私是一个重要的挑战。需要采用加密、访问控制等技术,来保护数据的安全和隐私。

9. 附录:常见问题与解答

9.1 为什么堆内存使用率会突然上升?

堆内存使用率突然上升可能有以下原因:

  • 大对象分配:程序中创建了大量的大对象,导致堆内存占用急剧增加。
  • 内存泄漏:程序中存在内存泄漏问题,导致一些对象无法被垃圾回收器回收,从而造成内存不断占用。
  • 业务高峰期:在业务高峰期,程序的并发量增加,创建的对象数量也会相应增加,导致堆内存使用率上升。

9.2 如何解决内存泄漏问题?

解决内存泄漏问题可以采取以下步骤:

  • 分析内存使用情况:使用性能分析工具,如VisualVM、YourKit Java Profiler等,分析堆内存的使用情况,找出内存占用过高的对象。
  • 检查代码逻辑:检查代码中是否存在对象引用没有及时释放的情况,如静态集合中保存了大量的对象引用、资源没有及时关闭等。
  • 优化代码:根据分析结果,对代码进行优化,如减少大对象的创建、及时释放不再使用的对象等。

9.3 如何设置JVM堆内存的大小?

可以通过JVM启动参数来设置堆内存的大小,常用的参数有:

  • -Xms:指定堆内存的初始大小。
  • -Xmx:指定堆内存的最大大小。

例如,设置堆内存的初始大小为512MB,最大大小为1024MB,可以使用以下命令:

java -Xms512m -Xmx1024m YourMainClass

9.4 堆内存使用率过高会导致什么问题?

堆内存使用率过高可能会导致以下问题:

  • 内存溢出异常:当堆内存空间不足时,程序在申请内存时会抛出OutOfMemoryError异常,导致程序崩溃。
  • 性能下降:堆内存使用率过高会导致垃圾回收的频率增加,从而影响程序的性能和响应速度。

10. 扩展阅读 & 参考资料

10.1 扩展阅读

  • 《Java并发编程实战》:这本书介绍了Java并发编程的原理和实践,对于理解多线程环境下的内存管理有很大帮助。
  • 《深入剖析Kubernetes》:这本书介绍了Kubernetes的内部原理和实践,对于了解云原生环境下的应用程序部署和管理有很大帮助。

10.2 参考资料

  • Java官方文档:https://docs.oracle.com/javase/8/docs/
  • VisualVM官方网站:https://visualvm.github.io/
  • YourKit Java Profiler官方网站:https://www.yourkit.com/java/profiler/
  • Spring Boot官方文档:https://spring.io/projects/spring-boot
  • Hibernate官方网站:https://hibernate.org/
  • Apache Kafka官方网站:https://kafka.apache.org/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值