簡體   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