如何在c#中尽可能快地填充内存

本文关键字:填充 内存 尽可能 | 更新日期: 2023-09-27 18:11:43

一位面试官刚刚问了我一个以前从未想过的特殊问题。

"如何在C#中尽快填充计算机内存?">

我回答说我可能会使用某种递归函数,但他指出,在填充内存之前,我可能会出现堆栈溢出。

我的问题很简单,如何使用C#尽可能快地填充计算机内存?

如何在c#中尽可能快地填充内存

我会用叉子炸弹:

while (true) Process.Start(Assembly.GetExecutingAssembly().Location);

这个概念很熟悉,程序会无休止地启动自己的新实例。

我还没有尝试过,但我会选择以下内容:

while(true) { Marshal.AllocHGlobal(1024); }
  1. 叉子炸弹,这最终会使CPU非常繁忙,但不一定会填满内存。如果您有GB的内存和一个小程序,Windows MMU可能最终会将未使用的(以前的fork(交换到磁盘,并为其他程序保留空闲内存。唯一的问题是,这并没有填满内存,相反,它只是使系统没有响应。

  2. 虚拟内存,通过使用Marshal分配巨大的对象。AllocHGlobal或类似的功能,你可能会认为你正在填充内存,但再一次,但操作系统更聪明,如果你只是分配内存,而不使用它们再次读取,操作系统会再次将它们分页回磁盘,仍然不会占用所有内存。这仍然是虚拟内存,操作系统将允许您最大限度地使用.net指南提供的内存,然后它将开始不再抛出内存,而不会实际消耗所有内存。

  3. 物理内存,现在这很棘手,首先,在任何应用程序的正常情况下,你都无法访问Windows中的物理内存。如果你真的想填充内存(物理内存(,那么你必须编写一个内核模式驱动程序来完成

  4. AllocateUserPhysicalPages函数。这是唯一一个允许您分配物理内存(以某种方式更快地填充内存(的Windows API,使其无法用于其他进程。https://msdn.microsoft.com/en-us/library/aa366528(VS.85(.aspx SQL Server使用它,我相信即使其他数据库也会使用它来预分配物理内存,这种内存更快,主要用于缓存目的。

创建一堆对象,避免它们被垃圾收集。

调用kill((并享受。

void kill()
{
    while(true)
        ThreadPool.QueueUserWorkItem(fill));
}
void fill(Object o)
{
    List<Object> list = new List<Object>();
    while(true)
        list.Add(new Object());
}

创建一个具有有效负载并实现终结器的类。然后生成多个优先级最高的线程,这些线程都创建了此类的实例。他们不必抓住他们,因为他们会进入终结器队列。终结器线程将无法跟上待终结的传入对象的速度,您将有效地填充进程内存。在32位系统上,这可能不足以填充计算机内存,但在64位系统上您应该能够在大多数系统上填充。

string text = File.ReadAllText("C:''Test''BigFile.any");

更新

我认为代码本身告诉了一切。因此,在你的计算机中找到一个大文件,例如一个像"D:''Movies''BigMovieFile.mp4"这样的电影文件。并将该文件作为字符串读取,因为string是一种非常消耗内存的类型。在32位的应用程序中,1Gb的文件将足以占用内存。由于64位应用程序将使用计算机的所有内存,因此必须选择一个较大的文件,或者必须重复读取过程我认为这种方法会尽可能快

这个问题似乎已经六年多没有得到回答了。如果有人仍然好奇,下面的代码可以工作。

using System.Management;
ObjectQuery objQuery = new("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher mgmtObjSearcher = new(objQuery);
ManagementObjectCollection mgmtObjColl = mgmtObjSearcher.Get();
var mgmtObj = mgmtObjColl.OfType<ManagementObject>().FirstOrDefault();
long freeBytes = long.Parse(mgmtObj.GetPropertyValue("FreePhysicalMemory").ToString()) * 1024;
long numOfArrays = freeBytes / 2000000000;
byte[][] memArray = new byte[numOfArrays][];
for (int i = 0; i < memArray.Length; i++)
{
    memArray[i] = new byte[2000000000];
}
for(int i = 0; i < memArray.Length; i++)
{
    for(int x = 0; x < memArray[i].Length; x++)
    {
        memArray[i][x] = (byte)x;
    }
}