DirectByteBuffer内存申请与释放

jvm堆外内存排查详解 内存泄漏想必大家并不陌生,对于jvm的内存泄漏,有很多排查手段和方便的排查工具,例如MAL,但是对于非jvm的内存,如直接内存的使用,排查起来较为麻烦,下面介绍一下相关的排查手段。 阅读详情
DirectByteBuffer类是在Java Heap外分配内存,对堆外内存的申请主要是通过成员变量unsafe来操作,下面介绍构造方法

    // Primary constructor
    //
    DirectByteBuffer(int cap) {                   // package-private

        super(-1, 0, cap, cap);
        boolean pa = VM.isDirectMemoryPageAligned();//内存是否按页分配对齐
        int ps = Bits.pageSize();//获取每页内存大小
        long size = Math.max(1L, (long)cap + (pa ? ps : 0));//分配内存的大小,如果是按页对齐方式,需要再加一页内存的容量
        Bits.reserveMemory(size, cap);//用Bits类保存总分配内存(按页分配)的大小和实际内存的大小

        long base = 0;
        try {
            base = unsafe.allocateMemory(size);//在堆外内存的基地址
        } catch (OutOfMemoryError x) {
            Bits.unreserveMemory(size, cap);
            throw x;
        }
        unsafe.setMemory(base, size, (byte) 0);//初始化堆外内存的数据为0
        if (pa && (base % ps != 0)) {
            // Round up to page boundary
            address = base + ps - (base & (ps - 1));//计算堆外内存的基地址
        } else {
            address = base;
        }
        cleaner = Cleaner.create(this, new Deallocator(base, size, cap));//释放内存会通过cleaner类操作
        att = null;
    }
假设堆外内存已经用了512K,pagesize=1024k,需要再分配 512个字节,为了使内存按页对齐,首先申请512+1024=1536个字节,新分配内存的基地址base=512+1024-(512&1023)=1024。

DirectByteBuffer类的内存里是在堆里申请的,但是通过基类Buffer的capacity,long address两个变量指向堆外的内存,如果在程序中创建了DirectByteBuffer类实例A,当A自身没有被引用时,在触发GC回收之前,jvm把A放在PhantomReference队列里,同时不断扫描PhantomReference队列,取出A,触发new Deallocator里的run方法回收堆外直接内存,同时回收A自身的堆内存.

Qt QChart实战:从零打造一个实时温度监控仪表盘(附完整源码) 本文详细介绍了如何使用Qt QChart模块从零构建一个工业级实时温度监控仪表盘。通过实战案例,展示了波形图的绘制、坐标轴配置、数据流模拟等关键技术,并提供了完整的源码实现,帮助开发者快速掌握Qt在数据可视化领域的应用。 阅读详情

相关推荐

INS/伪距组合导航(2)

伪距惯导组合导航

u014430081的博客 829

android 文件句柄,MappedByteBuffer文件句柄释放问题(示例代码)

问题描述现在很多java代码中都会用到内存映射的概念。文件映射的方法比输入输出流的方式快很多。但是在使用的过程中,正常地调用了FileChannel的force和close方法后,重命名文件或删除文件还会失败。主要原因还是文件的句柄没有释放。导致的问题分析及解决文件句柄如果被持有,就相当于jvm虚拟机中有一个指向文件的指针,所以重命名文件和删除文件都会导致失败。而MappedByteBuffer没...

weixin_39763683的博客 608

在Redroid容器中构建Frida RPC服务:自动化生成淘宝X-Sign签名参数

本文详细介绍了在Redroid容器中构建Frida RPC服务,实现自动化生成淘宝X-Sign等签名参数的完整方案。通过逆向分析定位关键方法,定制Redroid系统使Frida-Server常驻运行,并编写Frida脚本将签名方法暴露为RPC接口,最终封装为可远程调用的微服务,解决了签名生成的可移植性与工程化难题。

ice55的博客 645

堆外内存分析方法

进程的内存信息查看,知道内存中是什么内容后,可以进一步排查是否存在泄露的情况。有关,如果打印的字符串中没有嫌疑对象,可能意味着这块内存没有问题。通过上述步骤,可以看到对应内存地址中的字符串,若有堆外内存泄露,一般和。的问题时,在生产上的机器试验了下,并未查看到有问题的信息,记录下。的路径及前缀,需要确保程序对该路径有写入权限,生成的文件名格式为。观察堆内情况也是正常的,因此怀疑是堆外内存导致的。输出的结果,第一次为程序点火成功输出后,第二次是。分配情况,搜了一下其他的内存分配器,其中。

程序猿进阶 8000

手把手教你用ComfyUI搭建高效AI绘画工作流:从基础到高级技巧

本文详细介绍了如何使用ComfyUI构建高效的AI绘画工作流,从基础配置到高级技巧全面覆盖。通过模块化设计,ComfyUI显著提升显存利用率和创作灵活性,适合从新手到专业用户。文章包含部署指南、工作流搭建、性能优化及行业应用案例,帮助读者快速掌握AI绘画核心技术。

7up55的博客 720

Mac电脑用Latex论文排版3天速成5天实战de笔记

我后悔了,这五天竞赛搞得我视力都下降了...一个冲动的决定后成为数模竞赛论文写手,3天速成+5天时间=点亮攻克latex写论文技能💡关于Overleaf我是Mac,曾经按照大部分推荐的方式用TEXshop+vs code,但是把模板导入就开始报错。跟着少之又少的适配mac的教程(此时我已知道大概是走错路了)改了配置也无效。海鲜市场找佬改了半天,佬问我:一定要用VC吗?我说,那倒也不是。于是佬推荐我overleaf,三下五除二帮我挑配了环境,美汁汁收了我30块钱。

luwanjoyce的博客 2252

如何监控和诊断JVM堆内和堆外内存使用?

这里有一个相对特殊的部分,就是是堆外内存中的直接内存,前面的工具基本不适用,可以使用 JDK 自带的 Native Memory Tracking(NMT)特性,它会从 JVM 本地内存分配的角度进行解读。对于堆内存,我在上一讲介绍了最常见的新生代和老年代的划分,其内部结构随着 JVM 的发展和新 GC 方式的引入,可以有不同角度的理解,下图就是年代视角的堆结构示意图。在 JMC 或 JConsole 的内存管理界面,会统计部分非堆内存,但提供的信息相对有限,下图就是 JMC 活动内存池的截图。

雪雪 2201

R语言TCGA数据下载避坑指南:biolinks包实战中的5个常见错误与解决方案

本文详细介绍了使用R语言的TCGAbiolinks包下载TCGA数据时常见的5个错误及其解决方案,包括安装与加载问题、查询构建参数设置、下载中断处理、数据加载格式不匹配以及版本兼容性问题。通过实战案例和代码示例,帮助生物信息学研究者高效获取TCGA数据,避免常见陷阱。

weixin_30892037的博客 84

DirectByteBuffer内存申请与释放 && 可能会导致内存泄露的原因

DirectByteBuffer类是在Java Heap外分配内存,对堆外内存的申请主要是通过成员变量unsafe来操作,下面介绍构造方法    // Primary constructor    //    DirectByteBuffer(int cap) {                   // package-private        super(-1, 0, cap, cap);...

z69183787的专栏 3468

Windows Server 2012 R2虚拟机安装全攻略:从镜像选择到网络配置一步到位

本文提供Windows Server 2012 R2虚拟机安装全攻略,涵盖从镜像选择到网络配置的完整流程。详细讲解在Oracle VM VirtualBox中的安装步骤、TCP/IP网络设置、系统优化及常见问题解决方案,帮助用户快速搭建可立即投入使用的服务器环境。特别适合IT初学者和系统管理员学习传统服务器应用的部署与配置。

weixin_28363123的博客 541

K8s私有仓库拉取镜像报错解决:x509 certificate signed by unknown authority

在Kubernetes环境中使用自签名证书的私有Harbor镜像仓库时,常会遇到证书验证失败的问题。本文将详细讲解如何解决这个常见的证书问题。Kubernetes版本:1.28.2容器运行时:containerd 1.6.20私有仓库:Harbor(使用自签名证书)(超简单搭建私有仓库Harbor-亲测无坑解决K8s私有仓库证书问题的关键在于正确配置容器运行时(本例中是containerd)信任私有仓库的证书。

lzz的博客 2142

DirectByteBuffer 源码解读

转自:http://www.importnew.com/29817.html 在文章JDK源码阅读-ByteBuffer中,我们学习了ByteBuffer的设计。但是他是一个抽象类,真正的实现分为两类:HeapByteBuffer与DirectByteBuffer。HeapByteBuffer是堆内ByteBuffer,使用byte[]存储数据,是对数组的封装,比较简单。DirectByteBu...

jfengamarsoft的博客 387

地图之家总目录

地图之家总目录 cesium示例 leaflet示例

GIS之家家长 1万+

java heap buffer direct buffer_DirectByteBuffer内存释放

我们已经知道,在网络编程中,为了避免频繁的在用户空间与内核空间拷贝数据,通常会直接从内核空间中申请内存,存放数据,在Java中,把内核空间的内存称之为直接内存,nio包中的ByteBuffer的allocateDirect方法,就是帮助我们申请直接内存的,代码如下所示:publicstaticByteBufferallocateDirect(intcapacity){returnnew...

weixin_42475103的博客 346

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

nio 之HeapByteBuffer 和DirectByteBuffer

转载自 Unyieding 前面介绍了buffer 相关的概念以及如何使用ByteBuffer 进行读写nio 之 buffer 堆外内存和堆上内存 首先来讲一下什么是堆上内存,在java 中我们经常会编写类似下面一段代码 代码清单1-1 public class HeapByteBufferDemo { public static void main(String[] args) { ...

qq_36438618的博客 439

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

JDK 源码阅读 : DirectByteBuffer

Java编程精选点击右侧关注,免费入门到精通!来源:木杉的博客 ,imushan.com/2018/08/29/java/language/JDK源码阅读-DirectB...

<sdffdsfsdfdfs>sfsfsfsdfsdffds</sdfsDS>Fsd 232

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

java 申请内存_关于java直接内存

java1.4引入了nio.DirectByteBuffer,可能大部分同学在工作中跟直接内存打交道的并不多,本篇将结合网上资料查阅和自己的理解来对java直接内存和非直接内存做一个细致的整理。如有不合理之处,欢迎评论区留言。Netty服务端接收到消息体存储在ByteBuf中,接下来我们通过Debug的方式来跟踪一下ByteBuff的内存分配方式。客户端发送的消息体在服务端AbstractNioB...

weixin_29144939的博客 1526

Java NIO为何导致堆外内存OOM了?

某天报警:某台机器部署的一个服务突然无法访问。谨记第一反应登录机器查看日志,因为服务挂掉,很可能因OOM。这个时候在机器的日志中发现了如下的一些信息: nio handle failed java.lang.OutOfMemoryError: Direct buffer memory at org.eclipse.jetty.io.nio.xxxx at org.eclipse.jetty.io.nio.xxxx at org.eclipse.jetty.io.nio.xxxx 表明确实为OOM,问题是

JavaEdge全是干货的技术号 5368

Netty之Java堆外内存扫盲

Java的堆外内存本来是高贵而神秘的东西,只在一些缓存方案的收费企业版里出现。但自从用了Netty,就变成了天天打交道的事情,毕竟堆外内存能减少IO时的内存复制,不需要堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中;而且也没了烦人的GC。 好在,Netty所用的堆外内存只是Java NIO的 DirectByteBuffer类,通读一次很快。还有一些sun.misc.*的类

skiof007的专栏 314

堆外内存的回收机制分析

1.堆外内存 JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,比如Netty,广泛使用了堆外内存,但是这部分的内存并不归JVM管理,GC算法并不会对它们进行回收,所以在使用堆外内存时,要格外小心,防止内存一直得不到释放,造成线上故障。 2.堆外内存的申请和释放 JDK的ByteBuffer类提供了一个接口allocateDirect(int capacity)进行...

ai_xiangjuan的博客 1866

java nio 内存过大 限制_案例实战(三)Jetty 服务器的 NIO 机制是如何导致堆外内存溢出的...

案例发生现场有一天突然收到线上的一个报警:某台机器部署的一个服务突然之间就不可以访问了。此时第一反应当然是立马登录上机器去看一下日志,因为服务挂掉,很可能是OOM导致的崩溃,当然也可能是其他原因导致的问题。这个时候在机器的日志中发现了如下的一些信息:nio handle failed java.lang.OutOfMemoryError: Direct buffer memoryat org.ec...

weixin_36487107的博客 736

Java直接内存释放陷阱(90%开发者忽略的Cleaner与PhantomReference机制)

深入解析Java外部内存释放机制,揭示直接内存泄漏的常见陷阱。详解Cleaner与PhantomReference在堆外内存管理中的应用,适用于NIO、Netty等高性能场景,提升系统稳定性。掌握正确释放方法,避免内存溢出,值得收藏。

ByteVein的博客 850

JVM——15.定位 堆外内存 OOM

文章目录1. ByteBuffer 堆外内存介绍2. ByteBuffer 堆外内存申请、释放(源码分析)2.1 堆外内存申请2.2 堆外内存释放3. 什么情况会发生 堆外内存 OOM4. 模拟 堆外内存 OOM4.1 模拟14.2 模拟24.3 模拟35. 堆外内存 OOM 的定位及解决 1. ByteBuffer 堆外内存介绍 在介绍OOM那篇文章中,对堆外内存进行了介绍,就直接把它复制过来; ByteBuffer和DirectByteBuffer: ByteBuffer:字节缓冲区,它有两种实现:

m0_52325992的博客 1480

如何配置和管理直接内存?

直接内存的配置和管理核心是控制分配上限、规范申请释放、监控使用状态,避免内存溢出和泄漏

qq_74798973的博客 658

JVM学习打卡day06--直接内存

直接内存是Java程序绕过JVM堆,直接向操作系统申请的一块物理内存,也称为堆外内存(Off-Heap Memory)。它主要用于提升I/O操作的性能,是Java NIO实现高性能网络通信和文件处理的关键技术。

m0_61806863的博客 447
下一篇: AbstractReferenceCountedByteBuf 引用计数
ChainCode
ChainCode 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄11年 115粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值