今天我们讨论了垃圾收集中断需要多长时间。并且想知道简单地擦掉1千兆字节的内存需要多长时间。需要什么?
答案 0 :(得分:15)
在我的机器上,大约一秒钟:
#include <stdlib.h>
#include <stdio.h>
const long long int NUM = 1024*1024*1024/8;
int main(void) {
long long int* ptr = malloc(NUM * sizeof ptr);
printf("Gigabytes: %lld\n",NUM * sizeof ptr / 1024 / 1024 / 1024);
for(int i=0;i<NUM;i++) {
ptr[i]=1l;
}
}
然后我运行以下内容(它也不情愿地测量分配时间:
$ gcc -O3 -std=c99 mem.c -o mem
$ time ./mem
Gigabytes: 1
real 0m1.056s
user 0m0.205s
sys 0m0.845s
答案 1 :(得分:11)
您需要在此处考虑许多元素。我怀疑通用垃圾收集器在取消链接时清理内存 - 这将浪费时间。加上垃圾收集往往不是O(N)。垃圾收集通常会运行一些例程 - 这里最简单的一个就是压缩,压缩本身是基于已分配内存分配的统计信息。其他阶段也会有类似的复杂性。
- 在以下评论和问题后编辑
您选择的答案并没有让您更接近这种感觉 - 实际上它完全是误导性的 - 因为它不会迭代内存数据结构。它只是粗略地擦除内存,这不是垃圾收集器的工作。
更准确的答案
如果您想真正了解垃圾收集器,我建议您编写一个.NET或Java应用程序,并在不同大小的对象中初始化一个gig +内存,然后随机丢弃100-300mb的对象,然后重新创建它们再次随机大小;这样做几次通过混合。通过禁用收集器,丢弃一个价值的对象然后强制手动收集来遵循这一点;最后一个手动集合是您想要进行基准测试的 - 您希望这样做100次左右并绘制结果。
20秒后的备注
我确信有一些方法可以让收藏家以实时模式行事,如果这是你想要的。收集器不必进行完全扫描,可以将其编写为原子操作的集合,并且可以在实时超时(即20 ms)上禁用收集阶段。在这种情况下,它将完成部分收集,这仍然是有用的。
你必须调整我提到的策略来衡量在20ms内可以完成多少工作。请务必了解收集的数量更多地取决于存在的对象数量而不是它们的大小。因此,如果您决定正式测试GC,我建议捕获这两个值。
答案 2 :(得分:2)
人们会期望将1 GIG的内存返回到空闲池只是一些简单的指针操作。 GC通常不会清除返回的内存。
分配1 GIG内存的时间取决于当时O / S的运行情况 - 您必须设置页面表等...
答案 3 :(得分:2)
我前段时间测量了几款近期桌面机型的内存带宽,使用突发传输进行测试,并提出了一致的数字:大约每秒5千兆字节。这与Niko的数字非常匹配,一场演出0.205秒。在使内存可用时,会烧掉0.845秒的系统时间。这与你的硬盘驱动器的速度,页面文件的状态以及RAM中加载的其他程序页数有多大关系。
换句话说,您测量的任何内容都可能会下降400%或更多。有时甚至更多。