如何编写一个简单的“页面错误生成器”?

5

我需要模拟一种情况,即因内存不足而出现大量页面交换的情况,以便进行有关Linux内核的课程项目。

我想编写一个需要大量物理内存的程序,这样由此程序访问的页面将被多次交换进和交换出。


使用calloc。请参阅以下线程:http://superuser.com/questions/278855/a-linux-program-that-uses-memory和https://dev59.com/jlLTa4cB1Zd3GeqPa3xE。 - RaGe
2个回答

5

首先,您需要分配一个比RAM大小更大的缓冲区。我希望您正在运行64位操作系统或已启用PAE。如果您有4GB的RAM,则需要类似以下的东西:

double* pBigArray = (double*)malloc(sizeof(double) * 536870912); 
// You actually need more than that. This is just 4GB.

现在,仅拥有比RAM大小更大的数组是不够的。重要的是如何访问它。如果您只是连续读取元素,则CPU中的硬件预取器将会把一些程序将要读取的数据带到缓存中。
为了生成许多页面错误,您需要从不在RAM中的地址读取。
为此,有一个简单的方法,通过随机读取数组来实现:
double lfBigChecksum = 0.0;
while (true)
{
   int iIndex = rand() % BUFFER_SIZE;
   lfBigChecksum += pBigArray[iIndex];
}

如果您有一个8GB的数组和4GB的RAM,那么一半的读取将会是页面错误(并且会从硬盘中的交换空间中获取)。


好答案。只是好奇,为什么要分配“双精度”而不是单字节字符?他可以很容易地写malloc(4294967296ULL); - selbie
嗯,因为缓存行可以容纳的双精度浮点数较少(仅为8个),而字符则可以容纳64个,这样命中相同缓存行的机会就减少了。除此之外,没有其他真正的原因。 - VAndrei
1
此外,如果他正在运行32位操作系统,他将无法分配4GB。malloc会立即放弃并返回NULL。他可以在一个循环中分配100MB,直到malloc返回NULL。如果需要,在32位上可以有多个程序实例运行以强制页面交换。 - selbie
没错。希望他已经启用了64位或PAE。如果没有,你提出的方案似乎是一个不错的解决方案。 - VAndrei
以上代码需要注意一件事情。rand()只返回0-0x7fffffff之间的值。我猜如果他使用双数组而不是像我想的那样使用字符数组,这个问题就会隐式地解决。但是他可以在循环中这样说:size_t iIndex = rand()|(((size_t)rand())<<8) % BUFFER_SIZE; - selbie
显示剩余2条评论

-3

你可以通过动态分配大量空间并不使用它来消耗大量内存。例如在C++中,你可以这样做:

int *foo = new int[10000000];

这将会占用40MB的内存(假设你的int是4个字节),但并不会对其进行任何操作。如果多次执行此操作(可能需要在几个进程中分散执行),那么你的RAM将很快被耗尽。


根据我的理解,除非我使用分配的内存,否则物理内存不会受到影响(只有虚拟内存被分配)。这不是这种情况吗?David Grinberg - Neo
@Venkatesh,你正在“使用”它。在C++中我们使用了愚笨指针,它无法智能地判断你是否真正使用了它。仅仅通过声明就已经使用了内存。你可以自己试一下——在运行之前检查一下你的内存,然后运行这个程序,在其运行时再次检查内存(确保在结尾处加上while(true))。 - David says Reinstate Monica
1
我正在使用C语言。并且我使用int *foo = malloc(10000000);分配了动态内存。然而,我的RSS只有356 KB(由/proc/$pid/status报告)。 - Neo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接