我在跑步Fedora 26
。
这是我的算法教授给的一个非常奇怪的作业。作业说:
C 中的内存碎片:
设计、实现和执行执行以下操作的 C 程序: 为3m
每个数组大小为 800,000 个元素的序列分配内存;然后它显式地释放所有偶数数组并分配一个m
大小为 900,000 个元素的数组序列。测量您的程序分配第一个序列和第二个序列所需的时间。选择m
耗尽程序可用的几乎所有主内存。”
这样做的总体目标是对内存进行分段,然后请求比作为连续块可用的内存稍多的内存,从而迫使操作系统压缩或整理内存。
在课堂上我问我们应该如何做这件事,因为记忆是可视化的,实际上并不是连续的,他回答说:“好吧,你必须关闭 [虚拟记忆]。” 有同学在课堂上问我们怎么知道什么时候打到了这个“垃圾收集”,他说:“因为垃圾收集需要时间,所以第二次分配的时间应该比第一次大”
在四处搜索之后,我能找到的最接近禁用虚拟内存的方法是使用swapoff -a
. 我禁用了我的桌面环境,并从本机终端编译并运行了我的程序(以避免可能受到其他进程的干扰,尤其是像桌面环境这样的繁重进程)。我这样做并以递增的方式运行我的程序,m
直到达到第二次分配的时间大于第一次的时间点。
我用递增的方式运行程序,m
最终发现第二次分配的时间比第一次分配的时间多。然而,在此过程中,我遇到了在第二次分配之前进程被终止的情况。我检查了一下dmesg
,发现它是被oom
-killer杀死的。我发现并阅读了几篇关于oom
-killer 的文章,并发现您可以禁用内核过度分配内存。
我这样做并再次运行我的程序,只是这次我无法找到m
第二个时间高于第一个的时间。最终,随着 m 越来越大(虽然比启用过度分配时小得多),malloc 将失败,我的程序将终止。
我有三个问题,其中第一个问题并不那么重要:
垃圾收集是正确的术语吗?我的教授非常坚定地说这是垃圾收集,但我假设垃圾收集是由编程语言完成的,并且这会被认为是更多的碎片整理。
在 linux 系统上是否可以像他想要的那样进行压缩?
当我禁用交换但仍然启用内存过度分配时,为什么我能够达到第二次分配的时间高于第一次分配的时间?压实真的发生了吗?如果是这样,为什么在禁用内存过度分配后我无法达到压缩发生的程度?