首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

浅谈Linux内存管理那些事儿

当我们要学习一个新知识点时,比较好的过程是先理解出现这个技术点的 背景原因,同期其他解决方案,新技术点解决了什么问题以及它存在哪些不足和改进之处,这样整个学习过程是 闭环 的,个人觉得这是个很好的学习思路...slab分配器的基本原理 2 为什么需要管理内存 老子的著名观点是无为而治,简单说就是不过多干预而充分依靠自觉就可以有条不紊地运作,理想是美好的,现实是残酷的。...举个栗子: 在进行居民户籍管理时都会有区县市的概念,但是实际上并没有这种实体,都是逻辑上的,增加了这些行政单位之后可以让地址管理更加直接。...缺页中断( Page Fault )是只当软件试图访问一个虚拟地址时,经过段页转换为物理地址之后,此时发现该页并没有在内存中,这时 cpu 就会报出中断,再进行相关虚拟内存的调入工作或者分配工作,如果出现异常也可能直接中断...如果没有则查找下一个更大的块,在 order=1 的链表中找一个空闲块,链表中存在就把2个页框拆分,1个页框分配出去1 个页框加入到 order=0的链表中。

90420

CVE-2019-17498:libssh2整形溢出漏洞分析

当SSH服务器发送一条断开连接消息时,便会发生溢出。这也就意味着,该漏洞可以在连接过程的开始阶段,及身份认证完成之前被触发。...+ 9 + message_len); 越界读取通常来说会导致分段错误,但是本文所描述的问题将有可能导致代码调用第499行的LIBSSH2_DISCONNECT: if(session->ssh_msg_disconnect...它模拟了一个恶意SSH服务器,可以返回包含datalen==11和message_len==0x41414141的断开连接消息,这将导致libssh2出现分段错误并发生崩溃。...Liibssh2整型溢出变种分析 当我在将一个安全漏洞报告给厂商时,我通常会在报告中包含两个内容: 1、漏洞的漏洞利用代码PoC; 2、QL查询,识别所有我认为需要修复的代码位置; 在PoC中包含QL查询...比如说,message_len 一个比较表达式,而datalen-13则有可能发生溢出。我的查询还会重写isAdditionalFlowStep选项,并自定义数据流边界集。

1.3K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    谈一谈Windows中的堆

    这也是为什么有时候程序有时候溢出了几个字符,好像也没有导致程序异常或者崩溃的原因。 后置的元数据: 这个一般用于调试所用。一般发布的时候不会占用这块空间。 ? 那么哪些块是可以直接使用的呢?...而我们实际用户可用的内存是8字节 (最小分配粒度),比我们申请的5字节多了三个字节,这也是为什么程序有时候溢出了几个字符,并没有导致程序崩溃或者异常的原因。 0:000> !...Windows 自建堆的使用建议 在>>中建议了一些使用自建堆的场景,我用我自己的思路来解读解读。...当B i n Tr e e . c p p文件中的代码后来试图遍历二进制树时,它将无法进行这项操作,因为它的内存已经被破坏。当然,这使你认为二进制树代码中存在一个错误,而实际上错误是在链接表代码中。...由于不同类型的对象混合放在单个堆栈中,因此跟踪和确定错误将变得非常困难。 我个人认为在一个应用的工程中,也许不需要做到上述那么精细的划分。但是你想一想,在一个大型工程中,会混合多个模块。

    93830

    自有知识库训练-进阶篇

    上一篇文章介绍了,如何利用自有知识库的训练:突破chatGPT的局限性 这一篇文章,将继续探讨这一话题,把里面的一些技术细节展开 第一个细节,如何将文本分段 我们要理解为什么分段,本质是什么?...其次,分段也不能太短,太短了,信息就很割裂,上下文可能不会那么完整 所以这里面有一些策略,下面是我自己总结的一些策略: 最好的策略是自定义分段,这个比较适合你对文档很熟悉,你想把这个文档训练之后,提供给别人使用...,下图是我的一个实现: 但这个要求比较高,因为我们大多数场景看的并不是自己熟悉的文档 所以常用的策略是按照文档的自然的组织格式进行分段,比如段落和段落之间,一般都是二个换行符或以上,句和句之间...假设我现在想把一个文档分成每500个字一段,那我们该如何实现呢?...,所以最后的策略是,再把分出来的段再进行匹配组合,进可能让每一段接近500字 5、最后的最后,过滤掉一些不可见字符,占位符等,向量化,存入数据库,可以节省空间和token数 第二个细节,隐私问题 当我们进行自有知识库进行训练的时候

    68920

    深度 | 可视化线性修正网络:看Fisher-Rao范数与泛化之间的关系

    这个理论的基础是使用诸如权值衰减、甚至提前终止等技术,因为两者都可以被看作是保持神经网络权重向量有较小值的方法。根据一个神经网络权重向量的大小量级或范数而推理其泛化能力称为基于范数的容量控制。...对于没有修正的线性网络(实际上只是一个线性函数),Rademacher 复杂性可以用 FR 规范来界定,且边界不依赖于层数或每层单元的数量。...从这些图中不太清楚,为什么像这样的函数能够模拟数据,以及为什么如果我们添加偏置项会得到更一般的分段线性函数。...为什么是这样的? 以下是我的解释,与作者给出的简单证明略有不同。正如讨论的那样,一个通常的修正线性网络对于 x 是分段线性的。当我们改变 θ 时,线性分段的边界和斜率随之改变。...我认为目前缺少的是解释为什么 SGD 能够找到低 F-R 范数的解决方案,或一个解决方案的 F-R 范数是如何被 SGD 的批量大小影响的(如果有的话)。

    1.1K110

    【深度知识】Go语言:启动和内存分配初始化

    事实上,这个辅助向量是一个记录数组,这些记录存储着另外一些有用的信息,比如程序头的数量和大小等。更多关于 ELF 辅助向量的内容请参考这篇文章。 runtime.Args 函数负责处理这个向量。...每当我们希望分配新的 mspan、mcache、specialfinalizer 或者 specialprofile 结构体时,都可以通过 fixAlloc_Alloc 函数来调用分配器。...如果分配器已经没有足够多的空闲内存,则从 OS 申请更多的内存。 从分配器的缓存中返回所请求大小的内存。 persistentalloc 与 fixAlloc_Alloc 函数的工作机制是非常相似的。...一个亟需回答的问题是在函数开始时初始化的四个结构体到底有什么用: mspan 只是那些应该被垃圾回收的内存块的一个包装。在前面讨论内存大小分类时,我们已讨论过它了。...这并不是一个错误,mcache 只有在进程正在执行时才会初始化,而每当进程切换后它也重新切换为另外一个线程 m 结构体。

    2K20

    如何在Linux上获得错误段的核心转储

    步骤1:运行 valgrind 我发现找出为什么我的程序出现段错误的最简单的方式是使用 valgrind:我运行 1. valgrind -v your-program 这给了我一个故障时的堆栈调用序列...当您的程序出现段错误,Linux 的内核有时会把一个核心转储写到磁盘。 当我最初试图获得一个核心转储时,我很长一段时间非常沮丧,因为 – Linux 没有生成核心转储!我的核心转储在哪里?...从 gdb 中得到堆栈调用序列 你可以像这样用 gdb 打开一个核心转储文件: 1. $ gdb -c my_core_file 接下来,我们想知道程序崩溃时的堆栈是什么样的。...一旦我这样做了,当我执行 bt 时,gdb 给了我一个带有行号的漂亮的堆栈跟踪! 如果你想它能工作,二进制文件应该以带有调试符号信息的方式被编译。...本文中我不准备讨论那个,因为本文已经相当长了,并且在我的例子中打开 ASAN 后段错误消失了,可能是因为 ASAN 使用了一个不同的内存分配器(系统内存分配器,而不是 tcmalloc)。

    4.1K20

    《笨开发学习操作系统》3内存

    ,但你有没有想过操作系统是如何管理内存的?...但当我的游戏需要更多的内存的时候,是否我的视频就无法播放了呢? 那么对于操作系统来说,如何合理的分配和管理好内存就是我们今天要解决的问题。 虚拟地址 首先要引出一个概念:虚拟地址。...为什么需要虚拟地址 就像前言中所描述的,如果我们直接都使用物理地址会出现什么问题呢?...所以我们需要一个合理的数据结构来存放这样的映射关系。 分段存储 分段存储,顾名思义,就是将内存分为一段一段,如:代码段,数据段等等。访问时需要有两个东西:段号、段内地址(段内偏移)。...虚拟内存功能 共享内存:允许同一个物理页在不同的进程之间共享 COW(copy-on-write):写时复制,当我们使用 fock 系统调用创建子进程的时候,如果每次都需要将 task_struct 里面的所有内容都复制一次

    39610

    C语言函数:编程世界的魔法钥匙(2)-学习笔记

    终止条件就像是一个“刹车”,如果没有它,函数会不停地调用自身,导致无限循环,最终程序可能会因为栈溢出等错误而崩溃。因此,终止条件可以有效的防止代码的无限循环。...我们可以调试看一下 在调试过程中,系统会给这样一个错误,stack overflow叫 栈溢出       这道题出现栈溢出的原因就是因为该函数没有终止条件,出现死递归导致栈空间被持续占用而无法释放。...这就是为什么我们需要终止条件的原因。 以下是一些避免栈溢出错误的常见方法: 1. 优化函数调用 : 减少函数的嵌套调用层数,避免不必要的深层递归。对于可以使用迭代解决的问题,优先选择迭代而不是递归。...迭代的执行流程通常更直观,便于调试和查找问题。 4.可扩展性 在处理大规模数据或复杂问题时,迭代更容易进行优化和扩展,例如通过并行化或分段处理来提高效率。...尤其是当我试图解释迭代时,我甚至产生了放弃的念头,因为我觉得自己无法再向前推进。然而,考虑到我已经付出了很多努力,我不愿意就此放弃,所以我还是决定坚持把文章写完。

    6010

    硬核!美团秋招一面

    服务并发量高时,流量怎样负载均衡 14. 说说TCP的流量控制 15. TCP的拥塞控制 16. B+树 B-树的区别,为什么不用红黑树做索引 17....每个方法调用都需要在栈上分配一些内存,因此当方法调用链变得非常长时,栈的容量会耗尽,最终导致栈溢出异常。 无限循环递归:一个无限循环中,如果递归调用导致栈不断增长,最终可能导致栈溢出。...下面是一些原因,解释了为什么 JDK 8 放弃了分段锁: 内存开销:每个分段都需要维护一个独立的锁,这会导致内存开销增加,特别是当你有大量的分段时。...竞争条件:虽然分段锁减少了竞争的可能性,但当多个线程试图修改同一分段内的数据时,仍然可能发生竞争条件。这种情况下,需要线程等待并争夺分段级别的锁,可能导致性能下降。 11....一个比较简单的方法就是不断增加传输的水量,直到水管快要爆裂为止(对应到网络上就是发生丢包),用 TCP 的描述就是: 只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞

    44511

    为什么要重写 hashCode 和 equals 方法?

    然后他又问到另外一个问题: 你在用 HashMap 的时候,键(Key)部分,有没有放过自定义对象?...我说我放过,很自信的说我放过(其实我忘了我有没有放过),但是不能怂啊,第一个都不会了,第二个再说不会哪不是直接拜拜要走人了吗?...面试官狡猾的笑了,说是你既然没有重写过 hashCode 方法,你怎么把自定义对象放进去的? 我勒个去,原来你在这等着我呢,没想到这还是个连环炮,惹不起惹不起,认怂三连 ?...为什么要重写 equals 和 hashCode 方法 当我们用 HashMap 存入自定义的类时,如果不重写这个自定义类的 equals 和 hashCode 方法,得到的结果会和我们预期的不一样。...它们通过 hashCode 方法返回的 hash 值都是 103。 ? 当我们通过 k2 的 hashCode 到 103号位置查找时,确实会得到 k1。

    52120

    使用STL vector 作为XNAMath快速灵活的SIMD数据容器

    因为SSE/SSE2指令集要求数据必须对齐到16字节的边界, 所以vector的分配器必须替换成一个可以对齐的内存分配器(x86架构)....不管怎样, 我还是向他们的开源精神致敬, 时间会说明一切的. 内存布局 STL诞生的时候, SIMD没有像现在这么流行....加载没有对齐的数据到SIMD寄存器存在转换开销, 会比加载对齐数据慢大约两倍左右. Vector的对齐分配器 vector类使用默认的分配器进行new和delete的内存操作....在x86平台上, new操作符分配的内存是8字节对齐的. 如果想自定义内存分配, 那就需要重写分配器以支持16字节的内存对齐....函数参数也不是16位对齐的, 它会产生一个编译错误'C2719'. 非对齐类型XMFLOAT4是一个包含4个单精度浮点数的结构体, 可以用在堆内存对齐的vector类中.

    78430

    Go并不需要Java风格的GC

    为什么用Java更难做到这一点。 对Go GC的常见批评,以及为什么这种批评背后的许多假设往往是有缺陷的或完全错误的。...为什么Java比其他语言更需要快速的GC 基本上,Java将内存管理完全外包给它的垃圾收集器。事实证明,这是一个巨大的错误。然而,为了能够解释这一点,我需要介绍更多的细节。 让我们从头说起。...您可以在Go中创建指向由垃圾收集器管理的对象的指针。Go语言中,不需要像在c#中那样,将使用指针的代码单独标记出来。 自定义二次分配器 使用正确的指针,你可以做很多值类型做不到的事情。...因此,我要断言,通常情况下,尽管有许多警告,但对多线程程序使用压缩内存分配器并没有真正的优势。 分代GC和逃逸分析 Java垃圾收集器有更多的工作要做,因为它分配了更多的对象。为什么?我们刚刚讲过了。...现代的内存分配器,如谷歌的 TCMalloc 或英特尔的 Scalable Malloc 不会对内存进行分段。 在设计Java的时候,内存碎片是内存分配器的一个大问题。人们不认为这个问题可以解决。

    92530

    使用WebRTC开发Android Messenger:第1部分

    首先,在写的操作之前先进行检查,检查内存的当前值(转换为16位无符号整数)是否大于当前序列号。仅在为真时才执行写的操作。实际上,这并不是什么限制,当我测试它时,崩溃通常发生在两到三遍之后。...现代Android使用jemalloc,这是一个平板分配器,它不使用内联堆头,因此破坏堆元数据不是一种选择。相反,我使用符号编译了适用于Android的WebRTC,并将其加载到IDA中。...我以为也许我可以使用CVE-2020-6389覆盖长度并导致更大的溢出,但这存在一些问题。...由于此向量包含StunAttribute类型的虚拟对象,因此它将对每个元素执行虚拟调用,以调用它的析构函数。对越界内存的虚拟调用正是为什么移动指令指针的原因。...然后,我考虑使用一个已经释放的rtc :: Buffer对象,而不是使用其他对象,而使用特定的后备缓冲区大小,可以使用堆操作将其替换为包含指针的对象。这也没有解决。这在很大程度上是可靠性的问题。

    68220

    77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了

    否则内存是先返回给内存分配器,然后由内存分配器统一返还给系统,这就是为什么当我们调用 free 回收内存之后,再次访问这块内存时,可能不会报错的原因。...ok,现在我把上述测试程序改成私有匿名映射 这时再来看下内存的使用情况 我们可以看到,只有 used 增加了1G,而 buff/cache 并没有增长;说明,在进行匿名私有映射时,并没有占用 cache...3.4 共享匿名映射 当我们需要在父子进程共享内存时,就可以用到 mmap 共享匿名映射,那么共享匿名映射的内存是存放在哪了?我继续改写上述测试程序为共享匿名映射 。...这里就解释了为什么共享匿名映射内存初始化为0了,但是我们知道用 mmap 分配的内存初始化为0,就是说 mmap 私有匿名映射也为0,那么体现在哪了?...,内核2.6时,是用一个数组存储消息,而到了4.6则用红黑树了存储消息(我下载了这两个版本,具体什么时候开始用红黑树,没深究)。

    61620

    5分钟学会两年经验Linux运维都不懂的内核问题

    否则内存是先返回给内存分配器,然后由内存分配器统一返还给系统,这就是为什么当我们调用 free 回收内存之后,再次访问这块内存时,可能不会报错的原因。...ok,现在我把上述测试程序改成私有匿名映射 这时再来看下内存的使用情况 我们可以看到,只有 used 增加了1G,而 buff/cache 并没有增长;说明,在进行匿名私有映射时,并没有占用 cache...3.4 共享匿名映射 当我们需要在父子进程共享内存时,就可以用到 mmap 共享匿名映射,那么共享匿名映射的内存是存放在哪了?我继续改写上述测试程序为共享匿名映射 。...这里就解释了为什么共享匿名映射内存初始化为0了,但是我们知道用 mmap 分配的内存初始化为0,就是说 mmap 私有匿名映射也为0,那么体现在哪了?...,内核2.6时,是用一个数组存储消息,而到了4.6则用红黑树了存储消息(我下载了这两个版本,具体什么时候开始用红黑树,没深究)。

    65920

    77%的Linux运维都不懂的内核问题

    否则内存是先返回给内存分配器,然后由内存分配器统一返还给系统,这就是为什么当我们调用 free 回收内存之后,再次访问这块内存时,可能不会报错的原因。...当产生 oom 之后,函数 select_bad_process 会遍历所有进程,通过之前提到的那些因素,每个进程都会得到一个 oom_score 分数,分数最高,则被选为杀死的进程。...3.4 共享匿名映射 当我们需要在父子进程共享内存时,就可以用到 mmap 共享匿名映射,那么共享匿名映射的内存是存放在哪了?我继续改写上述测试程序为共享匿名映射 。 ?...这里就解释了为什么共享匿名映射内存初始化为0了,但是我们知道用 mmap 分配的内存初始化为0,就是说 mmap 私有匿名映射也为0,那么体现在哪了?...,内核2.6时,是用一个数组存储消息,而到了4.6则用红黑树了存储消息(我下载了这两个版本,具体什么时候开始用红黑树,没深究)。

    2K80

    77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了

    否则内存是先返回给内存分配器,然后由内存分配器统一返还给系统,这就是为什么当我们调用 free 回收内存之后,再次访问这块内存时,可能不会报错的原因。...ok,现在我把上述测试程序改成私有匿名映射 这时再来看下内存的使用情况 我们可以看到,只有 used 增加了1G,而 buff/cache 并没有增长;说明,在进行匿名私有映射时,并没有占用 cache...3.4 共享匿名映射 当我们需要在父子进程共享内存时,就可以用到 mmap 共享匿名映射,那么共享匿名映射的内存是存放在哪了?我继续改写上述测试程序为共享匿名映射 。...这里就解释了为什么共享匿名映射内存初始化为0了,但是我们知道用 mmap 分配的内存初始化为0,就是说 mmap 私有匿名映射也为0,那么体现在哪了?...,内核2.6时,是用一个数组存储消息,而到了4.6则用红黑树了存储消息(我下载了这两个版本,具体什么时候开始用红黑树,没深究)。

    49611

    Linux:信号的预备和产生

    问题3:前后台进程的理解 ——>当你在输入命令行的时候,其实bash进程就是前台进程,所以他得到了获取键盘输入的资格,而当我们执行一个可执行程序后,此时该可执行程序就变成了前台进程,而bash则变成了后台进程...——>因为未来这种方法可能会被多个信号当成他的自定义方法,所以如果handler方法没有这个参数的话,我怎么知道是因为收到哪个信号才进入handler函数的呢??所以我们必须得有这个参数!!  ...——>(1)进程pid :知道该闹钟隶属于哪个进程 (2)当前时间戳+参数=未来时间戳(只要当前时间戳大于未来时间戳,就表明超时了,就会给对应的进程发14号信号) 问题2:如果我用链表管理起来,我怎么知道哪一个要超时了呢...——>我们可以用一个优先级队列(小堆)管理起来,这样只要当前堆顶元素没有超时,那么整个优先级队列就都没有超时!!   2.5.4 core dume  core dump究竟是什么呢??...问题1:你都可以通过发信号、然后捕获来告知错误原因,那为什么还要多次一举形成一个core文件呢??

    7510

    RapidJson的设计实现解读

    GenericDocument的几个关键成员包括: Encoding:解析和存储编码格式 StackAllocator:栈的内存分配器,为什么需要这个呢,可以带来效能提升吗 Allocator:内存分配器...,可以用自带的,或者自己实现内存分配器, 1.3.1 内存分配器 `GenericDocument` 的缺省分配器是 `MemoryPoolAllocator`。...此分配器简单地读用标准的 `malloc()`/`realloc()`/`free()`。当我们需要许多增减操作,这种分配器会更为适合。...获取错误的原因,以及错误开始的位置的一个样例如下: Document d; if (d.Parse(json).HasParseError()) { fprintf(stderr, "\nError(...这个SAX还包含了以下的特性: 基于事件驱动模型,读取XML元素时触发回调方法 状态独立处理,元素处理不依赖于其他元素 串行化处理,只能逐个元素处理,没有回头路,不能回到文档的更早部分 2.1有哪些SAX

    3K432
    领券