- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
假设我们有一个创建并使用可能很大的vector<foo>
的方法。
已知最大元素数为maxElems
。
据我所知,C++ 11的标准实践是:
vector<foo> fooVec;
fooVec.reserve(maxElems);
//... fill fooVec using emplace_back() / push_back()
reserve
调用是否还有其他缺点(如果需要,可以用
shrink_to_fit()
释放这些内存)?
最佳答案
概括
使用太大的储备可能会有一些弊端,但是储备多少又取决于reserve()
的大小和上下文以及特定的分配器,操作系统及其配置。
您可能已经知道,在Windows和Linux之类的平台上,大的分配通常不会分配任何物理内存或页表项,直到它第一次被访问,因此您可能会想到大的未使用分配是“空闲的”。有时这称为“保留”内存而不“提交”内存,在此我将使用这些术语。
有一些原因可能使它不像您想象的那样免费:
页面粒度
上述的惰性提交仅在页面粒度下发生。如果您使用的是(典型)4096个字节的页面,则意味着如果您通常为一个 vector 保留4,000个字节,而该 vector 通常包含占用100个字节的元素,那么惰性提交不会为您带来任何好处!至少必须提交4096字节的整个页面,并且您不节省物理内存。因此,重要的不只是预期大小与保留大小之间的比率,而是保留大小的绝对大小决定了您将看到多少浪费。
请记住,许多系统现在都在透明地使用“大页面”,因此在某些情况下,粒度大约为2 MB或更大。在那种情况下,您需要大约10s或100s MB的分配才能真正利用惰性分配策略。
较差的分配性能
C++的内存分配器通常会尝试分配大块内存(例如,在类似Unix的平台上通过sbrk
或mmap
),然后将其有效地分解为应用程序所请求的小块。通过诸如mmap
之类的系统调用来获取这些大块内存可能比分配器中的快速路径分配(通常只有十几条指令)慢几个数量级。当您要求大块您通常不会使用的大块块时,您就会挫败这种优化,并且通常会走缓慢的道路。
举一个具体的例子,假设您的分配器向mmap
询问了128 KB的块,它将分配给分配的这些块。您在典型的vector
中分配了大约2K的内容,但reserve
为64K。现在,您将为每个其他mmap
调用支付一个reserve
调用,但是如果您只是要求最终需要2K,则mmap
调用将减少大约32倍。
对过量使用处理的依赖
当您需要大量内存而又不使用它时,您可能会遇到这样一种情况,即您需要的内存比系统支持的更多(例如,比RAM +交换的数量更多)。是否允许使用它取决于您的操作系统以及它的配置方式,并且如果您随后通过简单地编写更多内存来承担一些有趣的行为,则不管您打算做什么。我的意思是任意进程可能会被杀死,或者您在任何内存写入时都可能会遇到意外错误。由于overcommit tunables不同,在一个系统上有效的方法在另一个系统上可能会失败。
最后,由于监视工具报告的“VM大小”度量标准与流程最终提交的内容并没有太大关系,因此它使流程管理变得更加困难。
恶劣的地方
分配的内存超过了您的需要,可能会使您的工作集在虚拟地址空间中分布得更稀疏。总体效果是减少了引用位置。对于很小的分配(例如几十个字节),这可能会减少缓存行内的局部性,但是对于较大的分配,其主要作用可能是将您的数据分散到更多的物理页面上,从而增加了TLB压力。确切的阈值将在很大程度上取决于细节,例如是否启用了大页面。
关于c++ - Reserve()的高估是否有不利之处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45331719/
以下排序算法对什么样的数据输入有效/无效?快速排序、归并排序、堆排序、插入排序等 我知道至少有 2 个因素会影响排序算法的性能:1) 输入的大小,以及 2) 数据是否已经大部分排序。但我不确切知道这些
我正在为一个我还没有建立的网站做一些 SEO,它有这个导航栏: Profile
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我正在尝试使用 HTML5 中的标签更多地作为容器,因为此标签现在可以将 block 元素作为子元素,例如: 之前(有效的 XHTML 1.1) article title
我有一个重 ajax 的网站。我更新了地址栏中的散列值,以便存储浏览历史 - 因此前进和后退按钮仍然有效。例如,一个典型的用例是: site.com/directory#sports/1 site.c
如果我决定在我的网站中使用一些 javascipt,例如 $('#body').load(URL); 或 $.get(URL, {param:value}, function(){ ... }); 或
我正在我的网站 (wordpress) 上构建一个页面,我正在其中拉入多个帖子类型 people (url: site.com/people/name -of-person) 到名为 people (
我正在处理一个请求,该请求根据页面上项目的“状态”更改页面的 OG 元标记,这可能每隔几天就会更改一次。目标是在用户共享页面时显示与“当前状态”相关的内容,例如“X 正在发生!”而不是正常的“这是 X
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 4 年前。 Improve
我在一家将创建网络服务堆栈架构(基于概率论)的企业工作,我是相关技术负责人。该架构将使用 Java 平台创建,但我对一些团队成员有疑问:他们来自 Oracle 的老派(即他们使用 PL/SQL 完成了
我在 fiddler 上注意到 [RequireHttps] 执行状态代码 302 重定向而不是 301。我不确定这有什么意义...... 如果您说的是 Controller [RequireHttp
我是一名优秀的程序员,十分优秀!