[英]How to fill memory as fast as possible in c#
一位面试官刚刚问了我一个我以前从未想过的奇怪问题。
“你如何在 C# 中尽可能快地填充计算机的内存?”
我回答说我可能会使用某种递归函数,但是他指出我可能会在填充内存之前出现堆栈溢出。
我的问题很简单,如何使用 C# 尽可能快地填充计算机的内存?
我会用叉形炸弹去:
while (true) Process.Start(Assembly.GetExecutingAssembly().Location);
这个概念很熟悉,程序无休止地启动自己的新实例。
我还没有尝试过,但我会选择类似的东西:
while(true) { Marshal.AllocHGlobal(1024); }
Fork-Bomb,这最终会使 CPU 非常繁忙,但不一定会填满内存。 如果您有 GB 的内存和一个小程序,Windows MMU 最终可能会将未使用的(以前的分叉)交换到磁盘,并且仍然为其他程序保留可用内存。 唯一的问题是,这不会填满内存,而只会使系统无响应。
虚拟内存,通过使用 Marshal.AllocHGlobal 或类似函数分配巨大的对象,你可能认为你正在填充内存,但再次,但操作系统更聪明,如果你只是分配内存而不使用它们再次读取,操作系统将再次将它们分页回磁盘,仍然没有占用所有内存。 这仍然是虚拟内存,操作系统将允许您使用 .net 指南给出的 MAX 内存,然后它将开始不再抛出内存,而不会实际消耗所有内存。
物理内存,现在这很棘手,首先,在任何应用程序中,在正常情况下,您都无法访问 Windows 中的物理内存。 如果你真的想填充内存(物理内存),那么你必须编写一个内核模式驱动程序来完成它。
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.