我認爲,正如你似乎暗示的那樣,你有一個擁有許多成員的類,擁有大量的實例,並且需要同時將它們全部保存在內存中以執行計算。
我跑了一些測試,看看你是否可以爲你描述的類實際獲得不同的大小。
我用這個簡單的方法用於查找內存大小的物體:
private static void MeasureMemory()
{
int size = 10000000;
object[] array = new object[size];
long before = GC.GetTotalMemory(true);
for (int i = 0; i < size; i++)
{
array[i] = new Data();
}
long after = GC.GetTotalMemory(true);
double diff = after - before;
Console.WriteLine("Total bytes: " + diff);
Console.WriteLine("Bytes per object: " + diff/size);
}
這可能是原始的,但我發現它工作正常,像這樣的情況。
正如所料,對該類幾乎沒有什麼(將其轉換爲結構體,刪除繼承或方法屬性)會影響單個實例使用的內存。就內存使用情況而言,它們都是等同的。但是,儘量擺弄實際的類並通過給定的代碼運行它們。
您實際上可以減少實例的內存佔用量的唯一方法是使用較小的結構來保存數據(例如,int代替long)。如果你有大量的布爾值,你可以將它們分組成一個字節或整數,並且有簡單的屬性包裝器來處理它們(一個布爾值需要一個字節的內存)。在大多數情況下,這些可能是微不足道的東西,但對於一億個對象,刪除布爾值可能會導致百MB內存的差異。此外,請注意,您爲應用程序選擇的平臺目標可能會影響對象的內存佔用空間(x64構建佔用更多內存,然後x86構建)。
序列化數據不太可能有幫助。內存數據庫具有優勢,特別是在執行復雜查詢時。但是,實際上不太可能減少數據的內存使用量。不幸的是,減少基本數據類型的佔用空間的方法並不多。在某些時候,你只需移動到基於文件的數據庫。
但是,這裏有一些想法。請注意,它們非常有條件,會降低計算性能,並會使代碼難以維護。
它往往是在不同狀態的對象將僅具有一些性質填充大型數據結構的情況下,和其他將被設置爲空或默認值。如果你可以識別這些屬性組,也許你可以將它們移動到一個子類中,並且有一個引用可以爲null,而不是有幾個屬性佔用空間。然後,只有在需要時纔會實例化子類。你可以編寫可以隱藏代碼其餘部分的屬性包裝器。請記住,這裏最糟糕的情況是您需要將所有屬性保存在內存中,再加上幾個對象頭和指針。
您可能會將可能採用默認值的成員轉換爲二進制表示形式,然後將它們打包到字節數組中。你會知道哪些字節位置表示哪些數據成員,並可以編寫可以讀取它們的屬性。將最有可能具有默認值的屬性定位在字節數組的末尾(例如幾個long,通常爲0)。然後,在創建對象時,調整字節數組大小以排除具有默認值的屬性,從列表末尾開始,直到您擊中具有非默認值的第一個成員。當外部代碼請求屬性時,可以檢查字節數組是否足夠大以容納該屬性,如果不是,則返回默認值。這樣,你可以節省一些空間。最好的情況是,你將有一個指向字節數組的空指針,而不是幾個數據成員。最糟糕的情況是,您將擁有完整的字節數組,佔用原始數據的空間,併爲數組增加一些開銷。實用性取決於實際數據,並且假定您做的寫操作相對較少,因爲重新計算數組將會很昂貴。
任何希望這有助於:)
看起來也許你可以在這裏使用一個數據庫... –
這是不是一種選擇,因爲太多的代碼已經編寫並集成在C# – taminov