最近,我对关于事物浪费内存方面的实验数据着迷。下图显示了“开销因子”,计算为开销空间量除以可用空间,x 轴显示增长因子。我还没有找到一个很好的解释/模型来解释它所揭示的内容。
模拟片段:https ://gist.github.com/gubenkoved/7cd3f0cb36da56c219ff049e4518a4bd 。
模拟显示的形状和绝对值都不是我所期望的。
显示对最大有用数据大小的依赖性的更高分辨率图表在这里:https ://i.stack.imgur.com/Ld2yJ.png 。
更新。经过更多思考,我终于想出了正确的模型来解释模拟数据,并希望它能很好地匹配实验数据。这个公式很容易推断,只需查看我们需要包含的给定数量的元素所需的数组大小。
较早引用的 GitHub gist已更新,包括scipy.integrate
用于数值积分的计算,允许创建下面的图,该图很好地验证了实验数据。
更新 2.但是应该记住,我们在那里建模/模拟的内容主要与虚拟内存有关,这意味着过度分配的开销可以完全留在虚拟内存领域,因为物理内存占用仅在我们第一次发生时才会发生访问一个虚拟内存页面,因此可以访问malloc
一大块内存,但在我们第一次访问这些页面之前,我们所做的只是保留虚拟地址空间。我已经使用 CPP 程序更新了 GitHub要点,该程序具有非常基本的动态数组实现,允许更改增长因子和多次运行它以收集“真实”数据的 Python 片段。请参阅下面的最终图表。
结论可能是,对于虚拟地址空间不是限制因素的 x64 环境,不同增长因素之间的物理内存占用量可能几乎没有差异。此外,就虚拟内存而言,上述模型似乎做出了相当不错的预测!
模拟片段是g++.exe simulator.cpp -o simulator.exe
在 Windows 10 (build 19043) 上构建的,g++ 版本如下。
g++.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
PS。请注意,最终结果是特定于实现的。根据实现细节,动态数组可能会也可能不会访问“有用”边界之外的内存。一些实现将使用memset
对整个容量的 POD 元素进行零初始化——这将导致虚拟内存页面转换为物理内存页面。但是,std::vector
上面引用的编译器上的实现似乎并没有这样做,因此其行为与代码段中的模拟动态数组一样——这意味着在虚拟内存方面会产生开销,而在物理内存上可以忽略不计。