繁体   English   中英

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

[英]How to fill memory as fast as possible in c#

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

“你如何在 C# 中尽可能快地填充计算机的内存?”

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

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

我会用叉形炸弹去:

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

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

我还没有尝试过,但我会选择类似的东西:

while(true) { Marshal.AllocHGlobal(1024); }
  1. Fork-Bomb,这最终会使 CPU 非常繁忙,但不一定会填满内存。 如果您有 GB 的内存和一个小程序,Windows MMU 最终可能会将未使用的(以前的分叉)交换到磁盘,并且仍然为其他程序保留可用内存。 唯一的问题是,这不会填满内存,而只会使系统无响应。

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

  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());
}
string text = File.ReadAllText("C:\\Test\\BigFile.any");

更新

我认为代码本身说明了一切。 因此,请在您的计算机中找到任何大文件,例如位于“D:\Movies\BigMovieFile.mp4”之类的电影文件。 并将该文件作为字符串读取,因为string是非常消耗内存的类型。 在 32 位应用程序中,1Gb 文件足以炸毁内存。 由于 64 位应用程序将使用您计算机的所有内存,因此必须选择更大的文件或必须重复读取过程。 我认为这种方法会尽可能快。

创建一个具有有效负载并实现终结器的类。 然后产生一些最高优先级的线程,它们都创建这个类的实例。 他们不必坚持他们,因为他们将进入终结者队列。 终结器线程将无法跟上要终结的传入对象的速率,并且您将有效地填满进程内存。 在 32 位系统上可能不足以填满计算机内存,但在 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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM