草庐IT

c++ - 了解内存池

coder 2024-02-14 原文

根据我的理解,内存池是一个 block ,或者多个内存块在运行前在堆栈上分配。
相比之下,据我了解,动态内存是从操作系统请求的,然后在运行时在堆上分配。

//编辑//

  • 内存池显然不一定分配在堆栈上,即。内存池可以与动态内存一起使用。
  • 根据对这个问题的回答,显然非动态内存不一定分配在堆栈上。
  • “动态与静态内存”“内存池” 的主题因此并不真正相关,尽管答案仍然相关。

据我所知,内存池的目的是提供 RAM 的手动管理,其中内存必须由程序员跟踪和重用。

这在理论上有利于性能,原因有很多:

  1. 动态内存会随着时间的推移变得碎片化
  2. CPU 可以比动态 block 更快地解析静态内存块
  3. 当程序员可以控制内存时,他们可以根据特定程序选择在最佳时机释放和重建数据。

4. 多线程时,分离池允许独立线程独立运行,无需等待共享堆(Davislor)

我对内存池的理解是否正确?如果是这样,为什么内存池似乎不经常使用?

最佳答案

看来这个问题被XY problem 所阻碍了和 premature optimisation .

您应该专注于编写清晰代码,然后必要时使用分析器执行优化。

Is my understanding of memory pools correct?

不完全是。

... on the stack ...

... on the heap ...

存储持续时间与池的概念正交; 池可以分配为具有四种存储持续时间中的任何(它们是:静态、线程、自动和动态存储持续时间)。

C++ 标准不要求任何进入;将它们全部视为进入同一个地方可能会很有用...毕竟,它们都(通常)进入硅芯片!

... allocate ... before runtime ...

重要的是多个对象的分配发生在之前(或至少少于)这些对象首次被使用;这样就不必单独分配每个对象。我假设这就是您所说的“运行时 之前”的意思。选择分配大小时,您越接近在任何给定时间所需的对象总数,过度分配造成的浪费和过度调整大小造成的浪费就越少。

但是,如果您的操作系统不是史前时代,池的优势将很快消失。如果您在前后进行优化时使用分析器,您可能会看到这一点!

  1. Dynamic memory becomes fragmented over time

对于像 Windows 1.0 这样的原始操作系统来说,这可能是正确的。然而,在当今时代,具有分配存储持续时间的对象通常存储在虚拟内存中,它会定期写入磁盘并从磁盘读回(这称为分页) .因此,可以对碎片化的内存进行碎片整理,更常用的对象、函数和方法甚至可能最终合并到通用的页面中。

也就是说,分页为您形成了一个隐式(和缓存预测)!

The CPU can parse static blocks of memory faster than dynamic blocks

虽然分配了静态存储持续时间的对象通常位于堆栈上,但这并不是 C++ 标准强制要求的。完全有可能存在一个 C++ 实现,即 静态内存块 分配在堆上,而不是。

动态对象的缓存命中与静态对象的缓存命中一样快。 堆栈 通常保存在缓存中;您应该花些时间尝试没有堆栈的编程,您可能会发现缓存有更多空间供使用!

在优化之前,您应该始终使用分析器来衡量最重要的瓶颈!然后您应该执行优化,然后再次运行分析器以确保优化成功!

这不是一个机器无关的过程!您需要优化每个实现! 一个实现的优化可能对另一个悲观

If so, why does it seem like memory pools are not used very often?

上面描述的虚拟内存抽象,连同使用缓存分析器消除猜测,实际上消除了在所有情况下的用处,除了消息最少的(即< strong="">使用分析器) 场景。

关于c++ - 了解内存池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44253689/

有关c++ - 了解内存池的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  9. ruby-on-rails - 如何测试自己对 Ruby/ROR 的了解? - 2

    是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby​​和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T

  10. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

随机推荐