2012-10-23 25 views
8
var a = new double[7000,7000]; 

FillValue(a,3); 

Dường như .Net không thực sự cấp phát bất kỳ bộ nhớ nào cho a sau khi thực hiện dòng đầu tiên. Chỉ khi nó đang chạy cuộc gọi FillValue thì nó dần dần ăn bộ nhớ. (khoảng 400MB)tại sao không .net cấp phát bộ nhớ khi khởi tạo mảng 2d?

Có ai có thể cung cấp thêm thông tin chi tiết về nó không? Tôi nghĩ rằng a được lấp đầy với 0 sau khi khởi tạo mặc định, làm thế nào nó có thể không có bộ nhớ nào cả?

+4

Bạn đo lường xem nó có cấp phát bộ nhớ không? –

+0

@SethCarnegie thật đáng buồn, tôi đã sử dụng một cách rất thô lỗ ... chỉ cần nhìn vào cửa sổ công việc quản lý .. và thiết lập điểm break, chạy một vài lần trong một vòng lặp. Đó là bộ nhớ 400MB cho mỗi 'fill' rất dễ nhận biết. – colinfang

+1

Điều này cũng có thể là do hệ điều hành. Xem "Kết hợp bộ nhớ" http://blogs.msdn.com/b/b8/archive/2011/10/07/reducing-runtime-memory-in-windows-8.aspx –

Trả lời

9

Có hai cách để 'cấp phát bộ nhớ' trong Windows: để 'đặt trước' và bộ nhớ 'cam kết'.

Trình quản lý tác vụ chỉ hiển thị "Lịch sử sử dụng bộ nhớ vật lý"; .NET VM dường như chỉ sử dụng bộ nhớ dành riêng khi bạn cấp phát một mảng, và sau đó quay lại và cam kết các phần được sử dụng. Bằng cách này, bạn có thể dự trữ bộ nhớ mà không thực sự chiếm dụng bộ nhớ, hiệu quả hơn và tiết kiệm bộ nhớ, theo MSDN, "lưu trữ một phạm vi không gian địa chỉ ảo của quá trình mà không cần phân bổ bất kỳ lưu trữ vật lý thực tế nào trong bộ nhớ hoặc trong bộ nhớ". " tệp hoán trang trên đĩa ". Đó là lý do tại sao Task Manager không hiển thị nó.

Bạn có thể đọc thêm về trang này trên trang VirtualAlloc trên MSDN.

Mặc dù vậy, đây là chi tiết triển khai, do đó bạn không nên dựa vào nó hoặc bất kỳ thứ gì. Ví dụ, máy ảo Mono có khả năng hoạt động khác nhau.

+1

tôi đang nghĩ nếu chúng ta có thể tận dụng lợi thế của nó khi làm việc trên các thao tác ma trận thưa thớt. – colinfang

7

Trên thực tế nó cấp phát bộ nhớ như bạn có thể xem tại đây:

http://ideone.com/Cd4BR1

Console.WriteLine("Memory before: {0}",GC.GetTotalMemory(true)); 
var a = new double[5000,5000]; 
Console.WriteLine("Memory after: {0}",GC.GetTotalMemory(true)); 

Memory before: 118784 
Memory after: 200224768 

(cần thiết để giảm kích thước của mảng để ngăn chặn một OutOfMemoryException trên ideone)

GC.GetTotalMemory Method

Lấy số byte hiện được cho là được cấp phát.

+1

Ideone FWIW sử dụng Mono. –

+3

ví dụ tuyệt vời, thx, đã học một phương pháp mới ngay hôm nay :) – colinfang

Các vấn đề liên quan