Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL分表时机:100w?300w?500w?都对也都不对!

MySQL分表时机:100w?300w?500w?都对也都不对!

作者头像
JAVA葵花宝典
发布于 2021-06-17 06:19:20
发布于 2021-06-17 06:19:20
1.2K00
代码可运行
举报
文章被收录于专栏:JAVA葵花宝典JAVA葵花宝典
运行总次数:0
代码可运行

来源:juejin.cn/post/6957258784385269768

导读

以交友平台用户中心的user表为例,单表数据规模达到千万级别时,你可能会发现使用用户筛选功能查询用户变得非常非常慢,明明查询命中了索引,但是,部分查询还是很慢,这时候,我们就需要考虑拆分这张user表了。

如果此时,我们才去做分表,可能已经太晚了,为什么呢?

我以最典型的应用场景:用户筛选功能,以查询年龄在18到24岁的100位女性用户为例:

在单表的情况下,我们的SQL是这么写的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM user WHERE age >= 18 AND age <= 24 AND sex = 0 LIMIT 100

但是,拆分user表后,用户记录分散到了多张表,比如,分散到user_1user_2user_3这三张表,此时,要查询满足上面条件的用户,我们的查询过程就变成这样:

  1. 遍历user_1user_3这三张表
  2. 分别从三张表找出满足条件的用户,即执行上面的SQL
  3. 合并这些用户记录
  4. 从合并结果中过滤出前100名用户记录

通过对比,我们会发现分表后的查询过程跟单表相比,变化是比较大的,这势必导致我们不得不修改代码,如果系统内类似的情况很多,那么,可能引发系统较大规模的业务逻辑改动,所以,在系统真正出现数据库性能瓶颈前,必须提前规划分表方案,预留时间去做系统改造。

那么,问题来了,我们到底在单表数据规模达到多少时,做分表是最合适的呢?

在开头我提到分表的原因是因为单表数据规模太大,导致系统功能使用越来越慢,而影响数据库查询性能的因素很多,有并发连接线程数、磁盘IO,锁等等。但是,一条查询语句如果需要通过磁盘IO来获得查询结果,那么,无论是否存在数据库的并发查询请求,磁盘IO的性能瓶颈都会存在。而连接线程和锁导致的的性能问题,一般只有在高并发的场景下才会出现。所以,减少数据查询的磁盘IO,是我们在优化数据库查询性能时,最先需要考虑的。

那么,MySQL又是通过什么方法来减少数据查询的磁盘IO的呢?我们来看下面这张图:

image-20210128202928887.png

这是很典型的应用请求MySQL的示意图,从图中,我们很容易发现,MySQL为了避免查询时都从磁盘读取查询结果,所以,在磁盘和应用之间加了一层内存,尽可能将磁盘数据加载到内存,那么,下次查询请求访问MySQL时,可以从内存中获取查询结果,避免了过多的磁盘IO的读取

所以,通过MySQL对磁盘IO的优化方案,我们可以看出,只要把表中大部分数据缓存在内存中,那么,数据库的查询性能可以大大提升。结合user表来看,只要user表的数据规模可以保证大多数的数据可以加载到内存,那么,就不需要对user表拆分,反之,则需要拆分。

既然MySQL内存的大小决定了表何时拆分,那么,我们就先来看一下MySQL的内存结构吧

内存管理

MySQL的内存结构:

整个MySQL的内存主要分为3部分

Thread Memory:这部分内存空间是每个连接线程独享的,也就是说每个连接自身独立拥有自己的内存空间。连接释放时,内存就释放。所以,它是动态的。

Sharing:这部分是所有连接线程共享的内存空间。

InnoDB Buffer Pool:这部分就是InnoDB引擎层维护的一块内存空间,它也是共享给每个连接线程的。它是相对静态的内存,不会随连接的释放而释放。

其中,Thread Memory和Sharing属于MySQL Server层的内存空间,InnoDB Buffer Pool属于MySQL InnoDB层的内存空间

下面我再简单介绍一下上面3部分内存空间具体包含哪些部分:

Thread Memory
  • thread stack(线程栈):主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等。
  • sort_buffer:MySQL使用该内存区域进行记录排序。
  • join_buffer:在连表查询时,MySQL会使用该内存区来协助完成 Join操作。我会在《Join查询的极致优化》详细 讲解。
  • read_buffer:当查询无法使用索引时,需要全表扫描或全索引扫描来读取记录,那么,这时候,MySQL按照记录 的存储顺序依次读取数据页,每次读取的数据页首先会暂存在read_buffer中,该buffer写满或记录 读取完,就会将结果返回给上层调用。
  • read_rnd_buffer:和上面的顺序读取相对应,当 MySQL 进行非顺序读取(随机读取)数据页的时候,会利用这 个缓冲区暂存读取的数据。
  • net_buffer:这部分用来存放客户端连接线程的连接信息。
  • bulk_insert_buffer:当我们执行批量插入时,会使用该内存空间收集批量插入的记录,当该内存写满时,将该内 存中的记录写入数据文件。
  • tmp_table:临时表使用的内存空间。
Sharing
  • Key Buffer:MyISAM 索引缓存使用的内存空间。
  • Thread Cache:MySQL 为了减少连接线程的创建,将部分空闲的连接线程缓存在该内存区域,给后续连接使用。
  • InnoDB Log Buffer:这是 InnoDB 存储引擎的事务日志所使用的缓冲区。
  • Query Cache:缓存查询结果集的内存空间。
  • Table Cache:用来缓存表文件的文件句柄信息。
  • BinLog Buffer:用来缓存binlog的信息。
  • Table Definition Cache:用来缓存表定义信息。
  • InnoDB Additional Memory Pool:用来缓存InnoDB存储引擎internal 的共享数据结构信息。
InnoDB Buffer Pool
  • Index Page/Data Page:用来缓存InnoDB索引树的节点,包括非叶子节点的Index Page和叶子节点的Data Page。
  • Lock:用来缓存InnoDB索引树锁、AHI锁、数据字典锁等锁信息。
  • Dictionary:用来缓存InnoDB数据字典信息。
  • AHI:用来缓存InnoDB AHI结构相关信息。。
  • Change Buffer:用来存储change buffer信息。
  • LRU List/Free List/Flush List:InnoDB管理和维护索引树节点使用的几个链表,即使用这3个链表维护节点的增删 改查。

通过上面MySQL内存结构的讲解,我们得出2点:

  1. Thread Memory是连接线程独享的内存空间。
  2. Sharing和InnoDB Buffer Pool是连接线程共享的内存空间。

我们先来看下线程独享的内存空间Thread Memory是如何分配和释放的?

Linux内存结构

由于大多数情况,我们会把MySQL安装在Linux系统下,所以,MySQL连接线程独享的内存空间对Linux而言,就是Linux内存空间,所以,这里,我先讲解一下Linux中的内存结构是怎么样的?然后,再看一下它的分配和释放过程。

W311.png

上图为Linux系统分别在32位和64位情况下的内存结构。

32位

内核空间:从0xC0000000 ~ 0xFFFFFFF为内核空间,大小为1G,只有Linux系统自身可以访问,用户进程不能访问。

用户空间:从0x0 ~ 0xC0000000,大小为3G,Linux系统自身和用户进程都可以访问。

64位

内核空间:从0xFFF8000000000000 ~ 0xFFFFFFFFFFFF为内核空间,大小为128T,只有Linux系统自身可以访问,用户进程不能访问。

用户空间:从0x0 ~ 0x00007FFFFFFFF000,大小也为128T,Linux系统自身和用户进程都可以访问。

未定义:从0x00007FFFFFFFF000 ~ 0xFFF8000000000000,Linux未定义的空间。

用户空间

由于用户空间是我们进程使用的内存区,对MySQL而言,就是MySQL进程可以访问并控制的内存区域,所以,我们再详细看一下用户空间的内存结构:

W310.png

上图为Linux用户空间(用户态)的内存结构,叫做虚拟内存,它包括以下几部分:

  • 栈:包括局部变量和函数调用的上下文、调用返回地址等。
  • 文件映射:包括动态库、共享内存等,从高地址开始向下增长。
  • 堆:包括动态分配的内存,从低地址开始向上增长。
  • 数据段:包括全局变量等。
  • 只读段:包括代码和常量等。
内存分配

理解了用户空间内存的概念,我们再结合用户空间的概念,来看一下MySQL进程是如何分配和释放用户空间内存的

MySQL使用C标准库的malloc()在堆动态分配内存,使用mmap()在文件映射段动态分配内存。详细过程如下图:

上图为MySQL分配内存的过程,主要分Server层和InnoDB层两部分的内存分配。

通过上图,我们发现MySQL在Server层是通过malloc来分配内存的,而InnoDB层是通过mmap来分配内存的。(搜索公众号Java知音,回复“2021”,送你一份Java面试题宝典)

图中,我们从上往下看:

  1. MySQL Server层调用C语言的malloc函数申请分配内存
  2. malloc调用内存分配器从用户态向Linux内核申请内存,为什么有个内存分配器,这是什么?我们先来看一张图:

image-20210128234601866.png

这张图是malloc函数直接调用系统函数申请内存的过程,我们发现malloc通过brk和mmap这两个Linux系统函数从用户态向内核申请内存。这两个系统函数是干什么的呢

brk

image-20210128235723307.png

当申请内存大小小于MMAP_THRESHOLD这个内核参数配置的大小(默认128K)时,Linux系统使用brk来分配内存,上图展示了brk分配内存的过程,从上到下,假设内存总大小为50 + 20 + 20 = 90M:

  1. 进程1申请分配了50M堆内存
  2. 进程1执行结束,释放50M堆内存,如上图,50M内存区域变为虚线
  3. 进程2申请分配了20M堆内存,如上图,在50M堆内存右边又分配了20M
  4. 进程2执行结束,释放20M堆内存,如上图,中间20M内存区域变虚线
  5. 进程3申请分配了20M堆内存,如上图,在中间20M堆内存右边又分配了20M

通过brk分配内存的过程,我们发现,这些分配的堆内存释放后并不会立刻归还系统。所以,内存工作繁忙时,频繁的内存分配和释放会造成内存碎片。

mmap

image-20210128220606454.png

当申请内存大小大于MMAP_THRESHOLD这个内核参数配置的大小(默认128K)时,Linux使用mmap分配内存,上图展示了mmap分配内存的过程,从上到下,假设内存总大小为50 + 20 + 20 = 90M:

  1. 进程1申请分配了50M文件映射段的内存
  2. 进程1执行结束,释放50M文件映射段的内存,如上图,50M内存区域变虚线
  3. 进程2申请分配了20M文件映射段的内存,如上图,在原来50M内存区域内又分配了20M
  4. 进程2执行结束,释放20M文件映射段的内存,如上图,最左边20M内存区域变虚线
  5. 进程3申请分配了40M堆内存,如上图,在原来50M内存区域内又分配了40M内存,剩下10M仍是释放状态,为虚线

通过mmap分配内存的过程,我们发现mmap方式释放内存后会将内存及时归还给系统,避免 OOM。但是频繁的内存分配会导致大量的缺页异常,使内核的管理负担增大。这也是 malloc 只对大块内存使用 mmap 的原因。欧!!这里冒出一个新名词,缺页异常?别着急,我会在后面讲解。

通过malloc调用系统函数申请内存分配的过程,我们发现调用brk函数分配的内存在释放时不会归还给Linux系统,所以,导致了内存碎片,而过多的内存碎片会造成内存利用率下降。所以,Linux引入了一个内存分配器,用来管理和维护这些内存碎片,将碎片内存连接起来,提升内存的利用率。

内存分配器

内存分配器处在用户进程和内核态的内存之间,其采用内存池来管理和维护内存空间,它响应用户的分配请求,向Linux内核申请内存,然后将其返回给用户程序。

目前主流的内存分配器主要有三种:ptmalloc、tcmalloc和jemalloc。

关于内存分配器以及管理内存的策略和算法,将来在《Linux内核深度解读》新专题中,我会详细讲解。

缺页异常

在《mmap》这部分中,我提到了缺页异常,那么,什么是缺页异常呢?

在讲解缺页异常之前,我们先看一下《内存分配》这部分中的第一张图底部的虚拟内存管理,通过讲解它的工作原理,我们慢慢理解什么是缺页异常。

其实,虚拟内存管理器里面包含了许多组件,通过这些组件,虚拟内存管理器管理和维护进程用户态申请的内存和物理内存的关系。ps:用户态申请的内存,我们一般叫它虚拟内存。

整个虚拟内存管理器包含的组件有:

MMU:全称内存管理单元,它的作用是接收一个虚拟内存地址,将其转换为一个物理内存地址,然后,输出这个物理地址

Page Table:页表,Linux内核通过页表来维护虚拟内存地址和物理内存地址的映射关系,表中的每一条映射关系又叫做Page Table Entry,即页表项,缩写PTE,页表项地址缩写PTEA

讲完这些名词,我们再来看一下这张图:

image-20210128234749564.png

上图为一个虚拟内存管理器的工作原理,其中,VA全称虚拟地址,即虚拟内存的地址:

  1. 处理器生成一个虚拟地址,并把它传送给 MMU
  2. MMU 根据虚拟地址生成 VPN(虚拟页号,因为CPU与内存交互以页为单位),然后请求内存,获取 PTE 的数据。
  3. 内存向 MMU 返回 PTE 的数据
  4. 由于判断出 PTE 的有效位是 0,即内存中没有虚拟页号对应的物理页,所以 CPU 将出发一次异常中断,将控制权转移给内核中的缺页异常处理程序。
  5. 缺页异常处理程序确定出物理内存中的牺牲页,如果这个页面被修改过了(D 标志位为 1),那么将牺牲页换出到磁盘。
  6. 缺页处理程序从磁盘中调入新的页面到内存中,并且更新 PTE
  7. 缺页处理程序将控制权返回给原来的进程,再次执行导致缺页的指令。再次执行后,就会产生页命中时的情况了。

所以,mmap过程中讲到的缺页异常就是上面过程中所提到的缺页异常。

最后,通过上面Linux内存分配的各部分细节的讲解,我们再来回顾一下《内存分配》部分开头那张图

image-20210128234334536.png

server层

Server层内存分配的过程,见上图:

  1. MySQL调用系统函数malloc去申请内存
  2. malloc调用内存分配器向Linux内核申请内存,减少brk分配内存后产生的碎片
  3. 内存分配器调用系统函数brk或mmap向Linux内核申请内存 (1) 当申请内存大小小于MMAP_THRESHOLD这个内核参数配置的大小(默认128K)时,使用brk分配内存 (2) 当申请内存大小大于MMAP_THRESHOLD这个内核参数配置的大小(默认128K)时,使用mmap分配内存 当出现缺页时,Linux内核使用虚拟内存管理器的几个组件处理缺页异常
InnoDB层

如上图,InnoDB层采用Free、LRU和Flush List三个链表来管理InnoDB引擎相关的内存,也就是管理InnoDB Buffer Pool。

见上图,其中,MySQL在给InnoDB Buffer Pool申请内存时,直接调用系统函数mmap来完成内存的申请,这是由于InnoDB Buffer Pool缓存中的数据包含索引树、Change Buffer等等,这些都是大结构的数据,所以,MySQL不希望这些数据长时间占用内存,导致潜在的系统内存溢出的风险。

小结

通过MySQL底层内存分配和释放的详细分析,我们知道了MySQL在不同的内存结构中,使用了完全不同的内存分配和释放策略:

  1. Server层,即Thread Memory和Sharing:使用malloc申请并分配内存
  2. InnoDB层:即InnoDB Buffer Pool:使用mmap申请并分配内存,并使用Free、LRU和Flush List三个链表来维护内存

回到标题的问题:单表数据规模达到多大时进行分表最佳?

我们表数据(包含索引和记录)属于相对静态的数据,不随连接线程的释放而发生变化,结合MySQL的内存结构及分配和释放的过程,我们发现跟这些数据直接相关的内存区域就是InnoDB Buffer Pool,所以,我们只要看这个pool大小,来决定单表数据规模达到多大进行分表。即如果单表数据规模大小超过

InnoDB Buffer Pool的大小,就需要进行分表了。

InnoDB Buffer Pool的大小可以通过innodb_buffer_pool_size参数得到。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA葵花宝典 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2万字|30张图带你领略glibc内存管理精髓
看了下面所有的回答,要么是没有回答到点上,要么是回答不够深入,所以,借助本文,深入讲解C/C++内存管理。
高性能架构探索
2022/08/25
1.9K1
2万字|30张图带你领略glibc内存管理精髓
记一次内存占用问题的调查过程
最近在维护一台CentOS服务器的时候,发现内存无端"损失"了许多,free和ps统计的结果相差十几个G,搞的我一度又以为遇到灵异事件了,后来Google了许久才搞明白,特此记录一下,以供日后查询。
早起的鸟儿有虫吃
2020/06/07
4.1K0
技术分享 | MySQL: 压测结果很差怎么办
爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。
爱可生开源社区
2021/12/20
8330
技术分享 | MySQL: 压测结果很差怎么办
神秘!申请内存时底层发生了什么?
内存的申请释放对程序员来说就像空气一样自然,你几乎不怎么能意识到,有时你意识不到的东西却无比重要,申请过这么多内存,你知道申请内存时底层都发生什么了吗?
小林coding
2021/02/23
7360
神秘!申请内存时底层发生了什么?
万字长文,别再说你不懂Linux内存管理了,30 张图给你安排的明明白白
之前写了两篇详细分析 Linux 内存管理的文章,读者好评如潮。但由于是分开两篇来写,而这两篇内容其实是有很强关联的,有读者反馈没有看到另一篇读起来不够不连贯,为方便阅读这次特意把两篇整合在一起,看这一篇就够了!
程序员小猿
2021/01/19
2.7K0
万字长文,别再说你不懂Linux内存管理了,30 张图给你安排的明明白白
【操作系统】内存管理概述
常见的内存分配函数有malloc,mmap等,但大家有没有想过,这些函数在内核中是怎么实现的?换句话说,Linux内核的内存管理是怎么实现的?
嵌入式与Linux那些事
2024/05/11
2180
【操作系统】内存管理概述
一文读懂 Linux 内存分配全过程
在《你真的理解内存分配》一文中,我们介绍了 malloc 申请内存的原理,但其在内核怎么实现的呢?所以,本文主要分析在 Linux 内核中对堆内存分配的实现过程。
用户7686797
2021/05/11
1.7K0
一文读懂 Linux 内存分配全过程
一文浅析内存管理机制
众所周知,程序需要加载到物理内存才能运行,多核时代会出现多个进程同时操作同一物理地址的情况,进而造成混乱和程序崩溃。计算机当中很多问题的解决都是通过引入中间层,为解决物理内存使用问题,虚拟内存作为中间层进入了操作系统,从此,程序不在直接操作物理内存,只能看到虚拟内存,通过虚拟内存,非常优雅的将进程环境隔离开来,每个进程都拥有自己独立的虚拟地址空间,且所有进程地址空间范围完全一致,也给编程带来了很大的便利,同时也提高了物理内存的使用率,可同时运行更多的进程。
范蠡
2021/04/08
1.4K0
一文浅析内存管理机制
77%的Linux运维都不懂的内核问题
来源:高效运维 ID:greatops 前言 之前在实习时,听了 OOM 的分享之后,就对 Linux 内核内存管理充满兴趣,但是这块知识非常庞大,没有一定积累,不敢写下,担心误人子弟,所以经过一个一段时间的积累,对内核内存有一定了解之后,今天才写下这篇博客,记录以及分享。 【OOM - Out of Memory】内存溢出 内存溢出的解决办法: 1、等比例缩小图片 2、对图片采用软引用,及时进行 recycle( ) 操作。 3、使用加载图片框架处理图片,如专业处理图片的 ImageLoader 图片加
小小科
2018/06/20
2.1K0
频繁分配释放内存导致的性能问题的分析
1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看(pidstat也可以),
早起的鸟儿有虫吃
2019/05/05
7.2K0
频繁分配释放内存导致的性能问题的分析
【春节红包系列】一次"内存泄漏"引发的血案
2017年末,手Q春节红包项目期间,为保障活动期间服务正常稳定,我对性能不佳的Ark Server进行了改造和重写。重编发布一段时间后,结果发现新发布的Svr的机器内存一直在上涨。如下图示:
叫你不戴帽子
2018/05/29
7.1K4
【春节红包系列】一次"内存泄漏"引发的血案
为什么MySQL内存占用这么大? for InnoDB
这是 Innodb 引擎最重要的缓存,也是提升查询性能的重要手段。一般是global共享内存中占用最大的部分。在进行 SQL 读和写的操作时,首先并不是对物理数据文件操作,而是先对 buffer_pool 进行操作,然后再通过 checkpoint 等机制写回数据文件。占用的内存启动后就不会自动释放,默认通过LRU的算法镜像缓存淘汰,每次的新数据页,都会插入buffer pool的中间,防止前面的热数据被冲掉,长时间没动静的冷数据,会被淘汰出buffer pool,但是是被其它新数据占用了,所以一般这里不会释放的,除非重启(5.7 开始支持动态调整,默认以128M的chunk单位分配内存块)。innodb_buffer_pool主要包含数据页、索引页、undo 页、insert buffer、自适应哈希索引、锁信息以及数据字典等信息。
elontian田凌翔
2019/11/11
7.9K0
为什么MySQL内存占用这么大? for InnoDB
软件性能测试(连载9)
Linux内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。Linux的空间又分为内核空间和用户空间,在32位中,内核空间占1G,用户空间占3G;而在64位中,内核空间和用户空间各占128T。如图3-24所示。
顾翔
2020/02/20
9840
linux 内存管理初探
导语 linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux
郑剑
2017/08/11
10.1K2
linux 内存管理初探
进程内存管理初探
随着cpu技术发展,现在大部分移动设备、PC、服务器都已经使用上64bit的CPU,但是关于Linux内核的虚拟内存管理,还停留在历史的用户态与内核态虚拟内存3:1的观念中,导致在解决一些内存问题时存在误解。
刘盼
2020/06/19
2.5K0
进程内存管理初探
内存问题探微
因为这是我被问的最频繁的问题,哎呀我的程序 OOM 了怎么办,我的程序内存超过配额被 k8s 杀掉了怎么办,我的程序看起来内存占用很高正常吗?
范蠡
2020/12/15
9500
内存问题探微
Linux 了解内存使用
目前大部分的操作系统和应用程序并不需要16EB( 2^64 )如此巨大的地址空间, 实现64位长的地址只会增加系统的复杂度和地址转换的成本, 带不来任何好处. 所以目前的x86-64架构CPU都遵循AMD的Canonical form, 即只有虚拟地址的最低48位才会在地址转换时被使用, 且任何虚拟地址的48位至63位必须与47位一致(sign extension). 也就是说, 总的虚拟地址空间为256TB( 2^48 )
黄规速
2022/04/14
3.8K0
Linux 了解内存使用
十问 Linux 虚拟内存管理 ( 一 )
该文章介绍了如何通过 pmap 命令查看进程的虚拟地址空间使用情况,包括起始地址、大小、实际使用内存、脏页大小、权限、偏移、设备和映射文件等。通过分析这些信息,可以更好地了解程序运行时的内存使用情况,并找出潜在的内存泄漏、内存碎片等问题。
陈福荣
2016/11/02
11.5K0
十问 Linux 虚拟内存管理 ( 一 )
【Linux 内核 内存管理】内存管理架构 ② ( 用户空间内存管理 | malloc | ptmalloc | 内核空间内存管理 | sys_brk | sys_mmap | sys_munmap)
glibc 提供的 ptmalloc 函数 , FreeBSD 提供的 jemalloc 函数 , Google 提供的 tcmalloc 函数 ,
韩曙亮
2023/03/30
1.1K0
当Linux用尽内存
也许你很少面临这一情况,但是一旦如此,你一定知道出什么错了:可用内存不足或者说内存用尽(OOM)。结果非常典型:你不能再分配内存,内核会杀掉一个任务(一般是正在运行那个)。一般半随着大量的交换读写,你可以从屏幕和磁盘动向看出来。
一见
2018/08/10
5.1K0
推荐阅读
相关推荐
2万字|30张图带你领略glibc内存管理精髓
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验