[性能优化]-linux内存体系结构

第13章_I/O体系结构和设备驱动程序_《深入理解Linux内核(第三版)》 第13章是Linux内核“硬件交互层”的核心,核心目标是解决“内核如何与I/O设备通信”的问题——通过抽象的I/O体系结构屏蔽硬件差异,通过设备驱动程序作为“内核与硬件的中间翻译官”,最终为用户态提供统一的设备访问接口(如通过下的设备文件操作硬件)。 本章逻辑链:I/O硬件交互基础→设备驱动程序模型(统一管理)→设备文件(用户态入口)→具体设备驱动(字符、块设备),所有重难点均围绕“抽象适配”“性能优化”“统一接口”展开。要理解驱动程序,必须先掌握内核与I/O设备的底层交互方式,核心组件包括I/O端口、I/ 阅读详情

目录

 

[性能优化]-linux内存体系结构

1.说说linux内存分类

2.内存是怎么管理的?

3. 物理内存的分页技术

3.1 什么是分页技术

3.1.1 页帧的分配

3.1.2 进程分配内存

3.1.3 linux物理地址空间布局

3.1.4 linux虚拟地址内核空间分布

3.1.5 linux虚拟地址用户空间分布

3.1.6 linux虚拟地址与物理地址映射关系

3.2 虚拟内存管理

3.2.1伙伴系统( buddy system)

3.2.2分页回收

3.2.3 swap

4 总结

4.1 内存代码层优化

4.2 内存性能优化


[性能优化]-linux内存体系结构

second60 20180801

1.说说linux内存分类

在linux中,内存分两种:物理内存和swap交换内存。

 

物理内存:真正的内存,内存条里的内存,一个内存条4G,那么物理内存大小就 是4G。

swap交换内存:把一定的磁盘做为交换内存,为了物理内存不够用时,把内存中的 数据page out或swap out到交换内存中。

 

2.内存是怎么管理的?

进程是怎么使用内存的呢?是直接操作的吗?

答案当然不是。

 

linux可以同时运行成千上万的进程。每个进程都会占用一定的内存,如果进程直接操作内存,那么内存是根本不够用的。同时也不方便管理物理内存。如果一启动就把进程的所有内存分配好,那么会造成内存的浪费,因为可能运行过程根本不会运行到那。

 

根据上面原因,内核对内存管理做了处理:

  1. 内存采用分页技术,提高性能
  2. 内存和用户之间,加了一层虚拟内存
  3. 采用动态分配的方法使用内存
  4. 使用swap内存扩展内存
  5. 进程采用虚拟地址空间

 

3. 物理内存的分页技术

如果物理内存是按字节来存取,那么效率是比较差的。为了高效地管理内存和提升效率,采用了内存分页技术。

3.1 什么是分页技术

把内存分成固定大小的chunk组成,称为分页page。分页大小取决于处理器体系结构。i386和x86_64中的分页大小是4KB。内核以页大小处理内存。

系统上的物理内存被分成页帧(page frame),一个页帧包含数据的一个分页。

3.1.1 页帧的分配

   一个分页page是物理内存(page frame)或虚拟内存中一组连续性地址。通常4KB。

当一个进程请求一定数量的内存页时,如果有有效内存页,内刻立即分配给进程。

否则,需要从一些其他进程或分页缓存中得到。

3.1.2 进程分配内存

进程是不能直接对物理内存寻址的。每个进程有一个虚拟地址空间(32位为4GB)。当为一个进程分配内存时,页帧的物理地址被映射到进程的虚拟地址。

一个进程的虚拟地址空间大小取决于处理器构构。32位系统,一个进程虚拟地址空间大小2的32次方(4GB);64位系统上,大小为2的64次方(16EB)。然而,一个进程不会使用到那么多的地址空间,大部份是未分配的,并没有映射到任何物理内存。

以32位系统为例:

上图为一个进程在32位系统的虚拟地址空间图。

 

3.1.3 linux物理地址空间布局

以32位系统为例,内核地址空间划分为0-3G为用户空间,3-4G为内核空间。64位划分不同。

物理地址空间的顶部以下一段空间,被PCI设备IO内存映射占据,它们的大小和布局由PCI规范所决定。640K-1M这段地址被BIOS和VGA适配器所占据。

linux系统在初始化时,会根据实际的物理内存大小,为每个物理页面创建一个page对象,所有page对象构成一个mem_map数组。

内核将所有物理页面划分到3类内存管理区中

  1. ZONE_DMA(0-16m):,该区域的物理页面专门供IO设备的DMA使用。之所以需要单独管理 DMA的物理页面,是因为DMA使用物理地址访问内存,不经过MMU,并且需要连续 的缓冲区,所以为了能够提供物理上连续的缓冲区,必须从物理地址空间专门划分一段 区域用于DMA。
  2. ZONE_NORMAL(16M~896M):该区域的物理页面是内核能够直接使用的
  3. ZONE_HIGHMEM(896M~end):该区域即为高端内存,内核不能直接使用。

总结:内核使用0-1G的内存,其中896-1G中的128M给映射高端内存。1G以上的内存内核通过映射来操作。

3.1.4 linux虚拟地址内核空间分布

在kernel image下面有16M的内核空间用于DMA操作。位于内核空间高端的128M地址主要由3部分组成,分别为vmalloc area,持久化内核映射区,临时内核映射区。

由于ZONE_NORMAL和内核线性空间存在直接映射关系,所以内核会将频繁使用的数据如kernel代码、GDT、IDT、PGD、mem_map数组等放在ZONE_NORMAL里。而将用户数据、页表(PT)等不常用数据放在ZONE_ HIGHMEM里,只在要访问这些数据时才建立映射关系(kmap())。比如,当内核要访问I/O设备存储空间时,就使用ioremap()将位于物理地址高端的mmio区内存映射到内核空间的vmalloc area中,在使用完之后便断开映射关系。

3.1.5 linux虚拟地址用户空间分布

用户进程的代码区一般从虚拟地址空间的0x08048000开始,这是为了便于检查空指针。代码区之上便是数据区,未初始化数据区,堆区,栈区,以及参数、全局环境变量。

这个大家都很熟悉了,就不详细说明了,请看另一篇博客。

3.1.6 linux虚拟地址与物理地址映射关系

Linux将4G的线性地址空间分为2部分,0~3G为user space,3G~4G为kernel space。

由于开启了分页机制,内核想要访问物理地址空间的话,必须先建立映射关系,然后通过虚拟地址来访问。为了能够访问所有的物理地址空间,就要将全部物理地址空间映射到1G的内核线性空间中,这显然不可能。于是,内核将0~896M的物理地址空间一对一映射到自己的线性地址空间中,这样它便可以随时访问ZONE_DMA和ZONE_NORMAL里的物理页面;此时内核剩下的128M线性地址空间不足以完全映射所有的ZONE_HIGHMEM,Linux采取了动态映射的方法,即按需的将ZONE_HIGHMEM里的物理页面映射到kernel space的最后128M线性地址空间里,使用完之后释放映射关系,以供其它物理页面映射。虽然这样存在效率的问题,但是内核毕竟可以正常的访问所有的物理地址空间了。

 

问题:分配了1GB给虚拟地址空间给内核,够用吗?

答:在内核896-1024M,可以映射到其他的物理内存。所以不存在不够的问题。除非内存不够了。

3.2 虚拟内存管理

操作系统的物理内存对于应用程序和用户来说通常是隐藏的,因为操作系统可以将任何物理内存映射到虚似内存。

系统不会给应用程序分配物理内存,但是它会向linux内核请求一定大小的虚拟内存,并在虚拟内存中交换得到映射。

虚拟内存不必映射到物理内存。如果你的应用程序被分了大量内存,则有一部分可能被映射到磁盘的swap文件。

应用程序通常不直接向磁盘子系统写入,而是向高速缓存或缓冲区写入。当时间片到达,或者一个文件的大小超出缓冲缓存时,内核线程pdflush/Per-BDI flush会将缓存/缓冲中的数据刷新到磁盘中。

 

管理虚拟内存的默认配置是:分配所有有效的空闲内存空间作为磁盘的缓存。

同样,linux也可以非常有效地处理swap空间。

3.2.1伙伴系统( buddy system)

内核使用一种被称为伙伴系统的机制来维护它的空闲分页。伙伴系统维护空闲分页,并尝试给分页分配请求分页。它试图保持内存区域是连接的。

当分配分页失败时,会进行分页回收。

通过/proc/buddyinfo找到伙伴系统的信息。

3.2.2分页回收

当一个进程请求映射一定数量分页的时候,如果没有有效的分页,linux内核将尝试释放一定数量的分页,然后将这些分页分配给新的请求内存的进程。这个过程称为分页回收(pace reclaiming)。内核线程kswapd和内核函数try_to_free_page()负责分页回收。

分页的使用主要有两个目的:分页缓存和进程地址空间。分页缓存是分页被映射到磁盘的一个文件。分页属于一个进程地址空间,它被用于堆和栈。当kswapd回收分页时,它宁可缩小分页缓存也不愿分页移出进程拥有的分页。

 

分页缓存的分页回收和进程地址空间的回收在很大程序上依赖于使用场景,这将会影响性能。通过/proc/sys/vm/swappiness来控制这些行为.

3.2.3 swap

当发生分页回收时,在非活路列表中属于进程进址空间的候选分页可以被分页移出。目的保证主内存的分配和更加有效的利用空间。

虚似内存由物理内存和磁盘子系统或swap分区组成。如果linux中虚拟内存管理器发现内存分页已经被分配,但大量埋单还没有使用完,它会将这个内存分页移动到swap空间。

 

4 总结

内存是性能优化的最要一环。了解linux内存分配的原理,可以在写应用的内存使用时,可以更优的写出更优的代码。

4.1 内存代码层优化

1. 结构体对齐:可以使内存更小。可以学习C语言中的__attribute__选项

2. 内存预分配:在能预测到使用内存最大数量时,或限制最大量数时,预分配内存。

a) 减少内存碎片的产生,存减少创建消毁的开销

b) 缺点:预知估测好大小,占用一定的内存

3. 可以设置TCP接收和发送缓冲区大小和分页大小的N倍,如分页4K,缓冲设为8K.

4. 编写适合项目应用的内存分配函数。开源库基本都会提供一套自已的内存分配函数,为了更适合功能场景的内存分配。

 

4.2 内存性能优化

这个留在后面写。

 

Linux性能优化—内存实战篇 一、Linux内存工作原理 相关视频讲解: 深入讲解Linux内核内存管理(第一节) 深入讲解Linux内核内存管理( 第二节) Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈 1,内存映射   Linux内核给每个进程都提供了一个独立的虚拟空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。   虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(也就是单个CPU指令可以处理数据的最大长度)的处理器,地址空间的范围也不 阅读详情

相关推荐

Linux性能优化总结

Linux性能优化总结

小胡子 1367

Linux I/O缓冲区原理与性能优化实战

I/O缓冲区是现代操作系统的核心机制,通过在用户空间与物理设备之间建立数据中转层,显著提升系统吞吐量。其工作原理本质上是空间换时间的优化策略,利用内存缓冲暂存数据,通过批量处理减少磁盘I/O次数。在数据库、日志处理等高并发场景中,合理的缓冲区配置可使性能提升10倍以上。典型的Linux三级缓冲体系包含用户空间缓冲区、内核页缓存和磁盘控制器缓存,开发者可通过sync/fsync等系统调用控制数据持久化。结合内存映射、异步I/O等进阶技术,以及iostat、blktrace等诊断工具,能有效解决I/O等待高等性

weixin_31315567的博客 337

SAP ERP 物料主数据同步外围系统

w_input-beskz = i_marc_new-beskz."采购类型 " BESKZ--- ADD BY HX_FHJ 20210106。w_input-beskz = lw_marc-beskz."采购类型 " BESKZ--- ADD BY HX_FHJ 20210106。w_input-sobsl = i_marc_new-sobsl."特殊采购类型-虚拟物料标识。

ChampaignWolf的专栏 1744

linux进程虚拟空间布局

首先看linux进程的虚拟空间内存布局,以i386 32位机器为例每个用户进程的虚拟地址空间为0x0—0xC0000000也就是3GB,其中0x0—0x08000000 128MB地址空间用于捕获空指针,用户空间分为代码段,堆,mmap区,栈。堆的起始地址start_brk依据代码段和数据段的大小确定,堆从低地址往高地址增长,mmap区从高地址往低地址增长当两个区域相撞时则区域耗完,mmap区基地...

a7980718的专栏 1621

Silvaco Atlas新手入门:从安装到第一个半导体器件仿真(附DeckBuild配置)

本文为Silvaco Atlas新手提供了一份从软件安装、DeckBuild环境配置到完成第一个半导体器件仿真的实战指南。通过构建一个经典的PN结二极管案例,详细讲解了Atlas仿真语句的语法、核心命令顺序以及结果调试与可视化方法,帮助初学者快速上手并理解TCAD仿真流程。

sql99的博客 332

C#.NET斗地主服务端核心架构与高性能实现

斗地主作为典型的实时对战棋牌逻辑,本质是状态驱动的分布式协同问题。其技术内核涵盖有限状态机建模、低延迟网络同步、无GC内存操作与轻量级AI决策等关键能力。在.NET平台下,借助Span<T>、ImmutableArray、命令/事件总线与内存池等特性,可构建出高吞吐(200+ QPS)、低延迟(<150ms)、强一致的可落地服务端。本文聚焦C#.NET生态中斗地主核心模块的设计取舍与压测验证,深入解析状态机驱动、CardSet结构体优化、Kestrel中间件锁、规则+概率混合AI等实战方案,为实时对战类业务

weixin_29726381的博客 345

Linux内存布局详解

从堆段分配出nmemb*size字节的内存,即分配一块可容纳nmemb个元素、每个元素大小为size字节的数组的内存,将这块内存的初始化为0,并返回这块内存的起始地址。这个128KB可通过。:重新调整ptr所指向的已分配的内存大小为size字节,不会改变原来的内存的内容,也不会初始化新增的内存。从内存映射区申请内存,且释放时也可直接归还内存映射区的这块内存给内核,但是内核需要建立一系列复杂的数据结构来完成内存映射区的内存申请。:从堆段分配出size字节的内存,不会初始化这块内存,返回这块内存的起始地址。

llb_1203的博客 1900

从零到一:桌面宠物的硬件架构设计与工程实践

本文详细介绍了基于STM32F103C8T6主控平台的桌面宠物机器人硬件架构设计与工程实践。内容涵盖电源管理、舵机控制、PCB布局及系统调试等核心环节,为硬件爱好者提供从零到一的完整开发指南,助力打造稳定可靠的智能桌面伴侣。

alice7model的博客 1112

Linux物理内存组织结构

2 非一致性内存访问(Non-Uniform Memory Access, NUMA):内存被划分为多个内存节点,访问一个内存节点花费的时间取决于处理器和内存节点的距离,每个处理器都有一个本地内存节点,处理器访问本地内存节点的速度比访问其他内存节点的速度快。内存管理子系统使用节点(node)、区域(zone)、和页(page)三级结构描述物理内存。内存模型是从处理器的角度看到的物理内存分布情况,内核管理子系统支持3种内存模型。平坦内存(Flat Memory):内存的物理地址空间是连续的,没有空洞。

m0_74282605的博客 196

前端宝典之七:React性能优化实战精华篇

本文主要讲解实战项目中React性能优化的方法,主要分为三个大的方面:减少不必要的组件更新、组件优化以及tree-shaking,共11个方法

franktaoge的博客 1901

Android车载桌面开发实战:从CarLauncher源码解析到自定义Launcher开发(Android 11)

本文深入解析了Android 11中CarLauncher的源码架构与核心模块,并提供了从零开始定制开发车载Launcher的完整实战指南。内容涵盖车载桌面的独特定位、驾驶场景优化、多屏协同、动态内容嵌入等核心挑战,以及如何构建符合安全规范、体验流畅的自定义车载桌面应用,是车载应用开发者提升系统级定制能力的实用参考。

weixin_29266647的博客 516

linux虚拟内存结构

内核也是由一个elf文件(比如vmlinux)加载启动的,加载后也有text段,data段,bss段等。malloc的分配内存有两个系统调用,一个brk,一个mmap,brk是将.data的最高地址指针_edata往高地址走,mmap则是在进程的虚拟地址空间(在堆和栈之间的内存映射区域)找一块空间。通常,正文段是可共享的,所以即使是经常执行的程序(如文本编辑程序、C编译程序、shell等)在存储器中也只需要有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修改器自身的指令。C.非初始化数据段。

qq_27357145的博客 1222

4.Simulink基础建模操作——加减乘除运算

加减乘除运算

FPGA/MATLAB学习教程/源码/项目合作开发 9549

Linux系统内存介绍

内存是计算机的重要部件,也称内存储器或主存储器,它用于暂时存放CPU 中的运算数据,以及与硬盘等外部存储器交换的数据。它是外存与CPU 进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。只要计算机开始运行,操作系统就会把需要运算的数据从内存调到CPU 中进行运算。CPU 如果直接从硬盘中拿取数据,时间会太久。所以“内存” 作为中间人,从硬盘里面复制一份进来,再让CPU 直接到内存中拿数据做运算。这样会比直接去硬盘拿数据,快百万倍。

qq_31845173的博客 1921

五、实战pxe安装ubuntu 22.04 软raid1(实际生产pxe配置)

这段配置文件是一个cloud-init的自动安装配置,用于自动化部署Ubuntu服务器操作系统。它定义了从系统身份、键盘布局、区域设置到磁盘分区和RAID配置的一系列设置,并且包含了在安装过程的最后阶段执行的一些命令。基础设置version: 1指定了autoinstall配置文件的版本。source定义了安装源,这里是ubuntu-server。identity设置了主机名(hostname)、用户(username)和密码(password注意这里的密码是经过加密的。键盘与语言设置。

jundao1997的专栏 999

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Linux内存堆的空闲列表结构,[性能优化]-linux内存体系结构

目录linux[性能优化]-linux内存体系结构second60 201808011.说说linux内存分类在linux中,内存分两种:物理内存和swap交换内存。物理内存:真正的内存,内存条里的内存,一个内存条4G,那么物理内存大小就 是4G。swap交换内存:把必定的磁盘作为交换内存,为了物理内存不够用时,把内存中的 数据page out或swap out到交换内存中。 2.内存是怎么管理的...

weixin_29626189的博客 748

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

tipi 深入理解php内核 pdf_深入理解 Linux 内核--jemalloc 引起的 TLB shootdown 及优化

本文选自“字节跳动基础架构实践”系列文章。“字节跳动基础架构实践”系列文章是由字节跳动基础架构部门各技术团队及专家倾力打造的技术干货内容,和大家分享团队在基础架构发展和演进过程中的实践经验与教训,与各位技术同学一起交流成长。“延迟突刺”、“性能抖动”等问题通常会受到多方因素影响不便排查,本文以线上问题为例,详解 TLB shootdown,最终使得 CPU 的消耗降低 2% 左右,并消除了抖动突刺...

weixin_39593061的博客 246

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

温度PID控制PLC程序

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

linux 性能优化-内存优化

CPU 管理一样,内存管理也是操作系统最核心的功能之一。内存主要用来存储系统和应 用程序的指令、数据、缓存等。

大乐乐 2722

Linux性能优化之CPU、内存、IO优化

 Linux 的性能进行监测,以下是 VPSee 常用的工具:工具    简单介绍top    查看进程活动状态以及一些系统状况vmstat    查看系统状态、硬件和系统信息等iostat    查看CPU 负载,硬盘状况sar    综合工具,查看系统状况mpstat    查看多处理器状况netstat    查看网络状况iptraf    实时网络状况监测tcpdump    抓取网络数据...

赵英超的博客 2万+

【linux性能优化】linux内存如何工作

和CPU管理一样,内存管理是操作系统最核心的功能之一,内存主要用来存储系统和应用程序的指令、数据、缓存等 接下来看看Linux到底是怎么管理内存 一、内存映射 通常所说的内存容量,其实指的是物理内存 物理内存也称为主存,大多数计算机用的主存都是动态随机访问内存(DRAM) 只有内核才可以直接访问物理内存,那么,进程要访问内存时该怎么办呢? 1.1 虚拟内存 Linux内核给每个进程都提供一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存 虚拟地址空

sysu_lluozh 2776

Linux性能优化-内存优化

第二,共享内存 SHR 并不一定是共享的,比方说,程序的代码段、非共享的动态链接库, 也都算在 SHR 里。虽然每个进程的地址空间都包含了内核空间,但这些内核空间,其实关联的都是相同的物理内存。一个很典型的场景就是,即使内存不足时,有些应用程序也并不想被 OOM 杀死,而是希望能缓一段时间,等待人工介入,或者等系统自动释放其他进程的内存,再分配给它。所以,并不是所有的虚拟内存都会分配物理内存,只有那些实际使 用的虚拟内存才分配物理内存,并且分配后的物理内存,是通过内存映射来管理的。...

李嘉图呀李嘉图的博客 3711

linux性能优化-内存原理

linux性能优化-内存原理

张幺幺的博客——学习记录 3488

嵌入式linux内存和性能优化

一直在做嵌入式Linux系统的内存和性能优化,试着把自己这一年多来的知识和经验系统化,总结出来。初步出来个东西,还在不断更新中。1. 序 62. 内存 72.1. 系统当前可用内存 82.2. 进程的内存使用 92.2.1. 虚拟内存与物理内存 102.2.2. /proc/{pid} 112.2.

dongliqiang2006的专栏 1963

Linux性能优化之内存(二)

文章目录缓存命中率Swap 原理小结-1实战案例小结-2 缓存命中率 缓存的命中率是指直接通过缓存获取数据的请求次数,占所有数据请求次数的百分比。命中率越高,表示使用缓存带来的收益越高,应用程序的性能也就越好。 cachestat 和 cachetop是查看系统缓存命中情况的工具: cachestat 提供了整个操作系统缓存的读写命中情况。 cachetop 提供了每个进程的缓存命中情况。 下面就是一个 cachestat 的运行界面,它以 1 秒的时间间隔,输出了 3 组缓存统计数据: 上

Carroll的博客 1741

linux内存数据库,基于NoSQL内存数据库的Linux性能优化

或许你已经或多或少听说过某种NoSQL数据库了,如果NoSQL真的可以让我们的Web应用程序运行的更快、更具扩展性,我想我们可以去尝试,并尽可能发挥其威力。我们不仅要选择适合自己口味的NoSQL数据库,比如基于内存的Memcache或Redis,更适合企业级架构的Cassandra或HBase,同时,针对Linux服务器的优化也必不可少。另外,还有一个问题需要探讨。我们在尝试NoSQL数据库的时候...

weixin_31775717的博客 385

Linux性能优化之内存(一)

文章目录内存映射 内存管理也是操作系统最核心的功能之一。内存主要用来存储系统和应用程序的指令、数据、缓存等。 内存映射 Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。 虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(也就是单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,下面用两张图来分别表示它们的虚拟地址空间,如下所示: 进

Carroll的博客 2213
上一篇: [性能优化] - cpu调度原理
下一篇: [性能优化]-CPU与上下文切换
second60
博客等级 码龄9年 155粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值