Tôi đang tìm một cách để giữ cấu trúc mảng thưa thớt lớn 3d vào bộ nhớ mà không lãng phí nhiều bộ nhớ. Ở đây tôi đã thực hiện một thử nghiệm với các mảng của chờ đợi:Cách mảng lớn phân bổ bộ nhớ?
using System;
using System.Diagnostics;
using System.Runtime;
namespace ConsoleApp4
{
public class Program
{
static Process proc = Process.GetCurrentProcess();
const int MB = 1024 * 1024;
const int IMAX = 5;
const int JMAX = 100000000;
public static void ShowTextWithMemAlloc(string text)
{
proc.Refresh();
Console.WriteLine($"{text,-30}WS64:{proc.WorkingSet64/MB,5}MB PMS64:{proc.PrivateMemorySize64/MB,5}MB");
Console.ReadKey();
}
public static void Main(string[] args)
{
Console.Write(" ");
ShowTextWithMemAlloc("Start.");
long[] lArray = new long[IMAX * JMAX];
long[] l1Array = new long[IMAX * JMAX];
long[] l2Array = new long[IMAX * JMAX];
long[] l3Array = new long[IMAX * JMAX];
ShowTextWithMemAlloc("Arrays created.");
lArray[IMAX * JMAX - 1] = 5000;
l1Array[IMAX * JMAX - 1] = 5000;
l2Array[IMAX * JMAX - 1] = 5000;
l3Array[IMAX * JMAX - 1] = 5000;
ShowTextWithMemAlloc("Last elements accessed.");
for (var i=IMAX-1; i>= 0; i--)
{
for (var j=0; j<JMAX; j++)
{
lArray[i * JMAX + j] = i * JMAX + j;
}
ShowTextWithMemAlloc($"Value for row {i} assigned.");
}
//lArray = new long[5];
//l1Array = null;
//l2Array = null;
//l3Array = null;
//GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
//GC.Collect();
//ShowTextWithMemAlloc($"GC.Collect done.");
ShowTextWithMemAlloc("Stop.");
}
}
}
Nếu bạn muốn kiểm tra nó thiết lập các biến môi trường COMPlus_gcAllowVeryLargeObjects (Project Properties -> Debug) đến 1 hoặc thay đổi JMAX. Và đây là đầu ra:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15360MB
Last elements accessed. WS64: 15MB PMS64:15360MB
Value for row 4 assigned. WS64: 779MB PMS64:15360MB
Value for row 3 assigned. WS64: 1542MB PMS64:15360MB
Value for row 2 assigned. WS64: 2305MB PMS64:15361MB
Value for row 1 assigned. WS64: 3069MB PMS64:15361MB
Value for row 0 assigned. WS64: 3832MB PMS64:15362MB
Stop. WS64: 3844MB PMS64:15325MB
Khi tôi thấy mức tiêu thụ bộ nhớ trong Trình quản lý tác vụ giống như trong Process.WorkingSet64. Số thực là gì? Tại sao bộ nhớ được phân bổ khi gán? Là một mảng thực sự là một bộ nhớ phân bổ liên tục? Là một mảng một mảng? Người ngoài hành tinh có tồn tại không? (Kịch nhạc nền)
Episode 2: Chúng tôi làm cho một sự thay đổi nhỏ:
//lArray[i * JMAX + j] = i * JMAX + j;
var x= lArray[i * JMAX + j];
và không có gì thay đổi (trong đầu ra). Sự khác biệt giữa tồn tại và không tồn tại ở đâu? (nhạc nền kịch tính hơn) Bây giờ chúng tôi đang chờ câu trả lời từ một trong những người bí ẩn (Họ có một số và một chữ 'k' nhỏ dưới tên của họ).
Episode 3: Một sự thay đổi:
//lArray[IMAX * JMAX - 1] = 5000;
//l1Array[IMAX * JMAX - 1] = 5000;
//l2Array[IMAX * JMAX - 1] = 5000;
//l3Array[IMAX * JMAX - 1] = 5000;
//ShowTextWithMemAlloc("Last elements accessed.");
long newIMAX = IMAX-3;
long newJMAX = JMAX/10;
for (var i=0; i<newIMAX; i++)
{
for (var j=0; j<newJMAX; j++)
{
lArray[i * newJMAX + j] = i * newJMAX + j;
//var x= lArray[i * JMAX + j];
}
//ShowTextWithMemAlloc($"Value for row {i} assigned.");
}
ShowTextWithMemAlloc($"{newIMAX*newJMAX} values assigned.");
Sản lượng:
Start. WS64: 14MB PMS64: 8MB
Arrays created. WS64: 15MB PMS64:15369MB
20000000 values assigned. WS64: 168MB PMS64:15369MB
Stop. WS64: 168MB PMS64:15369MB
PMS64 cho một mảng (15.369-8)/4 = 3840MB Đây không phải là thưa thớt mảng, nhưng một phần mảng đầy;). Tôi đang sử dụng đầy đủ 168MB này.
Trả lời một số câu hỏi "Tại sao bạn không sử dụng kích thước chính xác?". Bởi vì tôi không biết? Dữ liệu có thể đến từ một số SQL do người dùng xác định. "Tại sao bạn không thay đổi kích thước nó?". Thay đổi kích thước tạo một mảng mới và sao chép các giá trị. Đây là thời gian để sao chép, bộ nhớ và vào cuối GC ác đến và ăn bạn.
Tôi đã lãng phí bộ nhớ. (Tôi không nhớ. Người ngoài hành tinh ?!) Và khi có, bao nhiêu? 0, (3840-168) MB hoặc (15369-8-168) MB?
Lời kết:
Nhận xét hoặc nhận xét?
là bộ nhớ tiếp giáp thực sự là bộ nhớ tiếp giáp?
Câu trả lời có đưa ra câu trả lời không? Bí ẩn. (more music)
(Scully: Mulder, cóc chỉ rơi từ trên trời xuống Mulder:!. Tôi đoán dù họ không mở)
Cảm ơn tất cả các bạn!
* Là một mảng thực sự là bộ nhớ được cấp phát liên tục? Là một mảng một mảng? Người ngoài hành tinh có tồn tại không? Vâng. Có lẽ, nhưng chúng * xa *. –
Tôi nghi ngờ câu hỏi (thực sự thú vị) mà bạn có thể đã bỏ lỡ là "Bộ nhớ thực sự là bộ nhớ"? ... và có lẽ "được rồi, nhưng khi bộ nhớ là bộ nhớ, bộ nhớ tiếp giáp thực sự là bộ nhớ tiếp giáp?" - Không, tôi thực sự không biết đủ về điều này để viết một câu trả lời. – moreON