如何在c#中尽可能快地填充内存
本文关键字:填充 内存 尽可能 | 更新日期: 2023-09-27 18:11:43
一位面试官刚刚问了我一个以前从未想过的特殊问题。
"如何在C#中尽快填充计算机内存?">
我回答说我可能会使用某种递归函数,但他指出,在填充内存之前,我可能会出现堆栈溢出。
我的问题很简单,如何使用C#尽可能快地填充计算机内存?
我会用叉子炸弹:
while (true) Process.Start(Assembly.GetExecutingAssembly().Location);
这个概念很熟悉,程序会无休止地启动自己的新实例。
我还没有尝试过,但我会选择以下内容:
while(true) { Marshal.AllocHGlobal(1024); }
-
叉子炸弹,这最终会使CPU非常繁忙,但不一定会填满内存。如果您有GB的内存和一个小程序,Windows MMU可能最终会将未使用的(以前的fork(交换到磁盘,并为其他程序保留空闲内存。唯一的问题是,这并没有填满内存,相反,它只是使系统没有响应。
-
虚拟内存,通过使用Marshal分配巨大的对象。AllocHGlobal或类似的功能,你可能会认为你正在填充内存,但再一次,但操作系统更聪明,如果你只是分配内存,而不使用它们再次读取,操作系统会再次将它们分页回磁盘,仍然不会占用所有内存。这仍然是虚拟内存,操作系统将允许您最大限度地使用.net指南提供的内存,然后它将开始不再抛出内存,而不会实际消耗所有内存。
-
物理内存,现在这很棘手,首先,在任何应用程序的正常情况下,你都无法访问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());
}
创建一个具有有效负载并实现终结器的类。然后生成多个优先级最高的线程,这些线程都创建了此类的实例。他们不必抓住他们,因为他们会进入终结器队列。终结器线程将无法跟上待终结的传入对象的速度,您将有效地填充进程内存。在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;
}
}