windows核心编程--虚拟内存

WINDOWS的内存管理【虚拟内存管理】(一) 导读:如果你已经对windows虚拟内存的概念有了一定认识,而只是想看一个例子,你可以跳过前面的基本概念。基本概念【摘录】       每个进程都被赋予它自己的虚拟地址空间。对于32位进程来说,这个地址空间是4GB,因为32位指针可以拥有从0x000000000至0xFFFFFFFF之间的任何一个值。这使得一个指针能够拥有4 294 967 296个值中的一个值,它覆盖了一个进程的4GB虚拟空 阅读详情
 

Wi n d o w s提供了3种进行内存管理的方法,它们是:
• 虚拟内存,最适合用来管理大型对象或结构数组。

• 内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据。

• 内存堆栈,最适合用来管理大量的小对象。


虚拟内存的状态
Wi n d o w s函数G l o b a l M e m o r y S t a t u s可用于检索关于当前内存状态的动态信息:
VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);
如果希望应用程序在内存大于4 G B的计算机上运行,或者合计交换文件的大小大于4 G B,那么可以使用新的G l o b a l M e m o r y S t a t u s E x函数:
BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst);

确定地址空间的状态
Wi n d o w s提供了一个函数,可以用来查询地址空间中内存地址的某些信息(如大小,存储器类型和保护属性等)。
这个函数称为Vi r t u a l Q u e r y:
DWORD VirtualQuery(
   LPCVOID pvAddress,
   PMEMORY_BASIC_INFORMATION pmbi,
   DWORD dwLength);
Wi n d o w s还提供了另一个函数,它使一个进程能够查询另一个进程的内存信息:
DWORD VirtualQueryEx(
   HANDLE hProcess,
   LPCVOID pvAddress,
   PMEMORY_BASIC_INFORMATION pmbi,
   DWORD dwLength);
这两个函数基本相同,差别在于使用Vi r t u a l Q u e r y E x时,可以传递你想要查询的地址空间信息的进程的句柄。调试程序和其他实用程序使用这个函数最多,几乎所有的应用程序都只需要调用Vi r t u a l Q u e r y函数。
为了获得完整的内存信息,我创建了一个函数,即V M Q u e r y:
BOOL VMQuery(
   HANDLE hProcess,
   PVOID pvAddress,
   PVMQUERY pVMQ);
系统信息

许多操作系统的值是根据主机而定的,比如页面的大小,分配粒度的大小等。这些值决不应该用硬编码的形式放入你的源代码。相反,你始终都应该在进程初始化的时候检索这些值,并在你的源代码中使用检索到的值。G e t S y s t e m I n f o函数将用于检索与主机相关的值:

 

VOID GetSystemInfo(LPSYSTEM_INFO psinf);


必须传递S Y S T E M _ I N F O结构的地址给这个函数。这个函数将初始化所有的结构成员然后返回。下面是S Y S T E M _ I N F O数据结构的样子。

 

typedef  struct  _SYSTEM_INFO
{
   union
   
{
      DWORD dwOemId;  
// Obsolete, do not use
       struct  
      
{
         WORD wProcessorArchitecture;
         WORD wReserved;
      }
;
   }
;
   DWORD     dwPageSize;
   LPVOID    lpMinimumApplicationAddress;
   LPVOID    lpMaximumApplicationAddress;
   DWORD_PTR dwActiveProcessorMask;
   DWORD     dwNumberOfProcessors;
   DWORD     dwProcessorType;
   DWORD     dwAllocationGranularity;
   WORD      wProcessorLevel;
   WORD      wProcessorRevision;
}
 SYSTEM_INFO,  * LPSYSTEM_INFO;


当系统引导时,它要确定这些成员的值是什么。对于任何既定的系统来说,这些值总是相同的,因此决不需要为任何既定的进程多次调用该函数。

表14-1 与内存有关的成员函数

成员名描述
d w P a g e S i z e用于显示C P U的页面大小。在x86 CPU上,这个值是4 0 9 6字节。在Alpha CPU 上,这个值是8 1 9 2字节。在I A - 6 4上,这个值是8 1 9 2字节
l p M i n i m u m A p p l i c a t i o n A d d r e s s用于给出每个进程的可用地址空间的最小内存地址。在Windows 98上,这个值是4 194 304,或0 x 0 0 4 0 0 0 0 0,因为每个进程的地址空间中下面的4 M B是不能使用的。在Windows 2000上,这个值是65 536或0 x 0 0 0 1 0 0 0 0,因为每个进程的地址空间中开头的6 4 K B总是空闲的
l p M a x i m u m A p p l i c a t i o n A d d r e s s用于给出每个进程的可用地址空间的最大内存地址。在Windows 98 上,这个地址是2 147 483 647或0 x 7 F F F F F F F,因为共享内存映射文件区域和共享操作系统代码包含在上面的2 GB分区中。在Windows 2000上,这个地址是内核方式内存开始的地址,它不足6 4 K B
d w A l l o c a t i o n G r a n u l a r i t y显示保留的地址空间区域的分配粒度。截止到撰写本书时,在所有Wi n d o w s平台上,这个值都是65536

该结构的其他成员与内存管理毫无关系,为了完整起见,下面也对它们进行了介绍(见表1 4 - 2)。

 

表14-2 与内存无关的成员函数

成员名描述
d w O e m I d已作废,不引用
W R e d e r v e d保留供将来使用,不引用
d w N u m b e r O f P r o c e s s o r s用于指明计算机中的C P U数目
d w A c t i v e P r o c e s s o r M a s k一个位屏蔽,用于指明哪个C P U是活动的(允许运行线程)
d w P r o c e s s o r Ty p e只用于Windows 98,不用于Windows 2000,用于指明处理器的类型,如Intel 386、4 8 6或P e n t i u m
w P r o c e s s o r A r c h i t e c t u r e只用于Windows 2000,不用于Windows 98,用于指明处理的结构,如I n t e l、A l p h a、Intel 64位或Alpha 64位
w P r o c e s s o r L e v e l只用于Windows 2000,不用于Windows 98,用于进一步细分处理器的结构,如用于设定Intel Pentium Pro或Pentium II
w P r o c e s s o r R e v i s i o n只用于Windows 2000 ,不用于Windows 98,用于进一步细分处理器的级别

在地址空间中保留一个区域

通过调用Vi r t u a l A l l o c函数,可以在进程的地址空间中保留一个区域:

 

PVOID VirtualAlloc(
   PVOID pvAddress,
   SIZE_T dwSize,
   DWORD fdwAllocationType,
   DWORD fdwProtect);

第一个参数p v A d d r e s s包含一个内存地址,用于设定想让系统将地址空间保留在什么地方。在大多数情况下,你为该参数传递M U L L。它告诉Vi r t u a l A l l o c,保存着一个空闲地址区域的记录的系统应该将区域保留在它认为合适的任何地方。系统可以从进程的地址空间的任何位置来保留一个区域,因为不能保证系统可以从地址空间的底部向上或者从上面向底部来分配各个区域。可以使用M E M _ TO P _ D O W N标志来说明该分配方式。如果Vi r t u a l A l l o c函数能够满足你的要求,那么它就返回一个值,指明保留区域的基地址。如果传递一个特定的地址作为Vi r t u a l A l l o c的p v A d d r e s s 参数,那么该返回值与传递给Vi r t u a l A l l o c的值相同,并被圆整为(如果需要的话) 6 4 K B边界值。

Vi r t u a l A l l o c函数的第二个参数是d w S i z e,用于设定想保留的区域的大小(以字节为计量单位)。由于系统保留的区域始终必须是C P U页面大小的倍数,因此,如果试图保留一个跨越6 2 K B的区域,结果就会在使用4 KB、8 KB或16 KB页面的计算机上产生一个跨越6 4 K B的区域。

Vi r t u a l A l l o c函数的第三个参数是f d w A l l o c a t i o n Ty p e,它能够告诉系统你想保留一个区域还是提交物理存储器(这样的区分是必要的,因为Vi r t u a l A l l o c函数也可以用来提交物理存储器)。若要保留一个地址空间区域,必须传递M E M _ R E S E RV E标识符作为F d w A l l o c a t i o n Ty p e参数的值。


最后一个参数是f d w P r o t e c t,用于指明应该赋予该地址空间区域的保护属性。与该区域相关联的保护属性对映射到该区域的已提交内存没有影响。无论赋予区域的保护属性是什么,如果没有提交任何物理存储器,那么访问该范围中的内存地址的任何企图都将导致该线程引发一个访问违规。

在保留区域中的提交存储器

当保留一个区域后,必须将物理存储器提交给该区域,然后才能访问该区域中包含的内存地址。系统从它的页文件中将已提交的物理存储器分配给一个区域。物理存储器总是按页面边界和页面大小的块来提交的。

若要提交物理存储器,必须再次调用Vi r t u a l A l l o c函数。不过这次为f d w A l l o c a t i o n Ty p e参数传递的是M E M _ C O M M I T标志,而不是M E M _ R E S E RV E标志。传递的页面保护属性通常与调用Vi r t u a l A l l o c来保留区域时使用的保护属性相同(大多数情况下是PA G E _ R E A D W R I T E),不过也可以设定一个不同的保护属性。

在已保留的区域中,你必须告诉Vi r t u a l A l l o c函数,你想将物理存储器提交到何处,以及要提交多少物理存储器。为了做到这一点,可以在p v A d d r e s s参数中设定你需要的内存地址,并在d w S i z e参数中设定物理存储器的数量(以字节为计量单位)。注意,不必立即将物理存储器提交给整个区域。
同时进行区域的保留和内存的提交

有时你可能想要在保留区域的同时,将物理存储器提交给它。只需要一次调用Vi r t u a l A l l o c函数就能进行这样的操作,如下所示:

 

PVOID pvMem  =  VirtualAlloc(NULL,  99   *   1024 ,   MEM_RESERVE  |  MEM_COMMIT, PAGE_READWRITE);


这个函数调用请求保留一个99 KB的区域,并且将99 KB的物理存储器提交给它。当系统处理这个函数调用时,它首先要搜索你的进程的地址空间,找出未保留的地址空间中一个地址连续的区域,它必须足够大,能够存放100 KB(在4 KB页面的计算机上)或104 KB(在8 KB页面的计算机上)。

系统之所以要搜索地址空间,原因是已将p v A d d r e s s参数设定为N U L L。如果为p v A d d r e s s设定了内存地址,系统就要查看在该内存地址上是否存在足够大的未保留地址空间。如果系统找不到足够大的未保留地址空间,Vi r t u a l A l l o c将返回N U L L,

如果能够保留一个合适的区域,系统就将物理存储器提交给整个区域。无论是该区域还是提交的内存,都将被赋予PA G E _ R E A D W R I T E保护属性。

最后需要说明的是,Vi r t u a l A l l o c将返回保留区域和提交区域的虚拟地址,然后该虚拟地址被保存在p v M e m变量中。如果系统无法找到足够大的地址空间,或者不能提交该物理存储器,Vi r t u a l A l l o c将返回N U L L。
回收虚拟内存和释放地址空间区域

若要回收映射到一个区域的物理存储器,或者释放这个地址空间区域,可调用Vi r t u a l F r e e函数:

 

BOOL VirtualFree(
   LPVOID pvAddress,
   SIZE_T dwSize,
   DWORD fdwFreeType);

改变保护属性

虽然实践中很少这样做,但是可以改变已经提交的物理存储器的一个或多个页面的保护属性。

若要改变内存页面的保护属性,可以调用Vi r t u a l P r o t e c t函数:

 

    BOOL VirtualProtect(
   PVOID pvAddress,
   SIZE_T dwSize,
   DWORD flNewProtect,
   PDWORD pflOldProtect);


当然,保护属性是与内存的整个页面相关联的,而不是赋予内存的各个字节的。因此,如果要使用下面的代码来调用4 KB 页面的计算机上的Vi r t u a l P r o t e c t函数,其结果是把PA G E _ N O A C C E S S保护属性赋予内存的两个页面:

 

VirtualProtect(pvRgnBase + (3 * 1024), 2 * 1024,
   PAGE_NOACCESS, &flOldProtect);

清除物理存储器的内容


为了说明内存的内容已经被清除,我们必须对系统的R A M提出大量的使用需求。若要进行这项操作,可以分3步来进行:

1) 调用G l o b a l M e m o r y S t a t u s函数,获取计算机中R A M的总容量。

2) 调用Vi r t u a l A l l o c函数,提交该数量的内存。这项操作的运行速度非常快,因为在进程试图访问页面之前,系统实际上并不为该内存分配R A M。

3) 调用Z e r o M e m o r y函数,使新提交的页面可以被访问。这将给系统的R A M带来沉重的负担,导致当前正在R A M中的某些页面被写入页文件。

如果用户指明该数据将在以后被访问,那么该数据将不被清除,并且在以后访问该数据时将数据转入R A M。但是,如果用户指明以后将不再访问该数据,那么数据将被清除,并且系统不把数据写入页文件,这样就可以提高应用程序的运行性能。


 

在Windows中设置虚拟内存的方法(编程) 虚拟内存是计算机系统中的重要概念,它允许操作系统将部分硬盘空间用作RAM的扩展。在Windows操作系统中,我们可以通过编程的方式来增加虚拟内存的大小。本文将详细介绍在Windows中增加虚拟内存的方法,并提供相应的源代码。请注意,以上代码只是一个示例,展示了如何通过编程的方式设置虚拟内存大小。如果您有任何进一步的问题,请随时提问。函数获取当前系统的内存信息,并打印出当前的虚拟内存大小。函数将进程的工作集大小设置为新的虚拟内存大小。函数获取更新后的系统内存信息,并打印出更新后的虚拟内存大小。 阅读详情

相关推荐

Dataworks实现接口调用

在本地linux虚拟机(不用在意linux版本),安装Anaconda后配置对应的虚拟环境,将虚拟环境的python包整体打包(路径一般为:~/anaconda/envs/env_name/lib/pyyhon3.7/site-packages):上传资源,将第三方包上传至dataworks(注意:所有上传文件均要打包上传,直接上传文件会乱码导致无法使用):PyODPS,其中PyODSP2的python版本为2.7,PyODSP3的python版本为3.7。:在PyODPS中引用资源,然后开发接口。

hutc_Alan的博客 1681

Windows内存修改初篇

​ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> BOOL FindFirst(DWORD dwValue);//对目标进程空间进行查找 BOOL FindNext(DWORD dwValue);//对目标空间进行2,3,4。。查找 //查找数据的地址列表 DWORD g...

用可见的方式来记录和分享每一次收获 849

ANSYS Discovery 2023R1 保姆级教程:手把手教你玩转几何模型参数化(附避坑指南)

本文提供ANSYS Discovery 2023R1几何模型参数化的全面教程,涵盖基础环境搭建、核心操作解析及高级应用场景。重点讲解参数化建模中的常见问题与避坑方案,帮助用户高效掌握Workbench与Discovery的协同使用技巧,提升工程仿真效率。

weixin_29204205的博客 752

windows C语言 修改文件

#include #include #include #include #include int ModifyFileData(char *file, unsigned long ulPosition, unsigned long ulDelBytes, char *buf, unsigned long ulAddBytes){ FILE *fp

yorloo的专栏 1410

Linux内核4.14版本——drm框架分析(1)——drm简介

drm框架分析

yangguoyu8023的博客 1万+

(数字ic验证)从零开始的apb_watchdog验证模块搭建(一、功能介绍与环境搭建)

apb_watchdog验证模块搭建(一)文章目录 文章目录apb_watchdog验证模块搭建(一)文章目录前言一、apb_watchdog简单功能介绍二、测试平台环境搭建1.测试所用模板介绍2.tb与interface2.env与watchdog_pkg3.test与base_sequence4.Makefile总结——当前验证结构 前言 本文介绍了apb_watchdog验证模块的搭建过程与其具体代码,主要包括其中验证环境的构建,测试序列的发送与回归测试收集。主要运用systemvorilog与u

peop1e的博客 9737

Windows内存管理 - 分配内核内存

Windows内存管理 - 分配内核内存

wendyWJGU的博客 1004

AUTOSAR-SOMEIP配置总结

导入arxml之后someip信号一般以“pduSomeIp”开头或者“SomeIp”开头。以某个pdu为例,设置项“Pdu Default Partition Ref”主要是根据模块设计,配置相应的Ecuc核分区。在导入arxml之后someip信号中有三个特殊的信号,形如“SdInstance”开头的信号,设置项“Pdu Default Partition Ref”主要是根据模块设计,配置相应的Ecuc核分区。“EcuC”模块主要关注“EcucPduCollection”中的“Pdus”下面的配置。

xiandang8023的博客 4653

Windows核心编程:探索虚拟内存

作者:shenzi链接:http://blog.youkuaiyun.com/shenziWindows核心编程:探索虚拟内存1.系统信息     操作系统中有许多值是由系统所运行的主机决定的,如页面大小和分配粒度等。我们应该在进程初始化时取得这些值,然后在代码中使用它们。GetSystemInfo函数用来取得与主机相关的值:

shenzi的天空 5130

Arduino、ESP32驱动AS3935数字闪电传感器(闪电传感器)

闪电传感器采用AMS独具创新的AS3935数字闪电传感芯片与Coilcraft的MA5532-AE专用天线,可在室内或室外,安全地检测方圆40km范围内发生闪电的距离,闪电相对强度与统计闪电发生次数。

不脱发的程序猿 2012

TPAMI 2024 | MO-MIX:基于深度强化学习的多目标多智能体协同决策

深度强化学习(RL)已被广泛应用于解决复杂的决策问题。在许多现实世界的场景中,任务通常有多个相互冲突的目标,并且可能需要多个智能体进行合作,这些是多目标多智能体决策问题。然而,在这个交叉领域的研究工作还相对较少。现有的方法仅限于单独的领域,并且只能处理具有单一目标的多智能体决策,或者具有单一智能体的多目标决策。在本文中,我们提出了MO-MIX来解决多目标多智能体强化学习(MOMARL)问题。我们的方法基于集中训练与分散执行(CTDE)框架。

小白学视觉 1129

Windows核心编程 - 在应用程序中使用虚拟内存(2)

接着上一篇Windows核心编程 - 在应用程序中使用虚拟内存(1) 4. 何时调拔物理存储器 假设正在实现一个电子表格的应用程序,需要一个CELLDATA结构来描述单元格的内容。一种最简单的方式使用二维数组这种数据结构来实现,数组的优点是访问速度快,但缺点是意味着程序一开始运行就需要从页交换文件中分配大量的物理存储器,但实际上用户通常只会使用少数的单元格,造成内存的浪费。 ...

yjianlu的专栏 221

老电脑续命神器:Windows 11 26H1 精简游戏版,帧率稳定无压力!(Win11 26H1 极致精简游戏版(3.17G):装完只占 8G 内存,Ultra CPU 性能拉满)

旧电脑福音也能安装windows11畅玩游戏🎮:文章分享一款 Windows 11 26H1 精简游戏版,仅 3.17G、C 盘占用 8G,开机进程约 50 个,内存占用 1.4G,内置游戏优化与运行库,支持离线安装、跳过 TPM 检测,让老电脑也能畅玩 3A 游戏和办公娱乐 🚀。

XiaoqiangClub的博客 1062

Windows核心编程:在应用程序中使用虚拟内存

Windows核心编程:在应用程序中使用虚拟内存    Microsoft Windows提供以下三种机制来对内存进行操控:虚拟内存:最适合用来管理大型对象数组或大型结构数组。内存映射文件:最适合用来管理大型数据流(通常是文件),以及在同一机器上运行的多个进程之间共享数据。堆:最适合用来管理大量的小型对象。      

shenzi的天空 3519

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

基于visual c++之windows核心编程代码分析(6)分配和释放可读可写的虚拟内存页面

我们在进行Windows核心编程,经常要用到读取虚拟内存。我们来亲自实践一个分配与释放可读可写的虚拟内存页面,请见代码实现与注释讲解。#include #include /************************************* * int main(void) * 功能 演示虚拟内存的使用 * * 参数 未使用 ******************************

尹成的技术博客 3481

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

WINDOWS核心编程--虚拟内存

WINDOWS核心编程--虚拟内存windows内存管理每个进程都被赋予它自己的虚拟地址空间。对于32位进程来说,这个地址空间是4GB,因为32位指针可以拥有从0x00000000至0xFFFFFFFF之间的任何一个值。这是虚拟地址空间,不是物理地址空间。该地址空间只是内存地址的一个范围。在你能够成功地访问数据而不会出现违规访问之前,必须赋予物理存储器,或者将物理存储器映射到各个部分的地址

xuwei2007的专栏 2248

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

[笔记]Windows核心编程《十五》在应用程序中使用虚拟内存

文章目录前言一、预定地址空间区域1.1 VirtualAlloc函数二、给区域调拨物理存储器三、同时预定和调拨物理存储器四、何时调拨物理存储器五、撤销调拨物理存储器及释放区域六、改变保护属性七、重置物理存储器的内容 前言 Microsoft Windows 提供三种机制来对内存进行操控: 虚拟内存 最适合用来管理大型对象数组或大型结构数组 内存映射文件 最适合用来管理大型数据六(通常是文件) 堆 最用来适合管理大量的小型对象 一、预定地址空间区域 1.1 VirtualAlloc函数 LPVOID W

二次元怪兽的博客 1121

windows核心编程-虚拟内存

Microsoft Windows 提供了三种机制来对内存进行操作。 1、堆-----------最适合用来管理大量的小型对象。 2、虚拟内存-----最适合用来管理大型对象数组或大型结构数组。 3、内存映射文件-最适合用来管理大型数据流(通常是文件),以及在同一机器上运行的多个进程之间共享数据。 接下来我来介绍一下虚拟内存中用到的几个函数。 LPVOID VirtualAl

程序人生的专栏 1573

[笔记]Windows核心编程《十四》探索虚拟内存

[笔记]Windows核心编程《十四》探索虚拟内存

二次元怪兽的博客 1173

Windows 核心编程之14 探索虚拟内存

探索虚拟内存

软件开发 1778

Windows核心编程 - 探索虚拟内存

1. 系统信息 操作系统中有很多参数是由系统所运行的主机所决定的,如页面大小和分配粒度等,可使用GetSystemInfo函数来获取与主机相关的参数。为了让32位应用程序能够在64位版本Windows上运行,Microsoft提供了一个称为Windows 32-bit On Windows 64-bit的模拟层,称为WOW64。当32位应用程序在WOW64上运行时,调用GetSystem...

yjianlu的专栏 292

在进程空间使用虚拟内存(Windows 核心编程)

虚拟内存空间 如今的 Windows 操作系统不仅可以运行多个应用程序,还可以让每一个应用程序享受到约 4 GB 的虚拟内存空间(...

墨鱼菜鸡 237

《Windows核心编程》读书笔记十四 探索虚拟内存

第十四章  探索虚拟内存 本章内容 14.1 系统信息 14.2 虚拟内存状态 14.3 NUMA机器中的内存管理 14.4 确定地址空间的状态 本章通过分析一些windows函数来了解与系统内存管理和进程中虚拟地址空间相关的信息。 14.1 系统信息 操作系统有许多值是由运行主机决定的。如页面大小和分配粒度。不应该将这些参数写死(硬编码到代码中)而是应该在

sesiria的博客 806

虚拟内存——Windows核心编程学习手札之十四

虚拟内存——Windows核心编程学习手札之十四系统信息有些操作系统的值是根据主机而定的,如页面大小、分配粒度大小等,这些值不用硬编码形式,进程初始化时应检索这些值以使用。函数GetSystemInfo函数用于检索与主机相关的值:VOID GetSystemInfo(LPSYSTEM_INFO psinf);传递SYSTEM_INFO结构的地址,该函数将初始化结构成员并返回。

医疗影像检索 2852
上一篇: windows核心编程--内存结构
下一篇: windows核心编程--内存映射文件
Mobidogs
博客等级 码龄21年 186粉丝 264原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值