2011-01-27 41 views
14

Tôi phải tạo một mảng đôi khá lớn 12000 x 55000. Thật không may, tôi nhận được một ngoại lệ bộ nhớ. Tôi đã từng phát triển trong Java và có thể thay đổi các thiết lập bộ nhớ. Điều này có thể với C# hoặc là nó chỉ là không thể? Tôi đang sử dụng VS 2008.OutOfMemoryException khi khai báo mảng lớn

+1

A * khá * mảng lớn? :) – Groo

+0

Tôi khuyên bạn nên xem xét cấu trúc dữ liệu "ngoài bộ nhớ chính" (tức là cơ sở dữ liệu). Tại sao bạn phải lưu trữ một mảng lớn như vậy? – bitxwise

+0

Tôi đã cười khúc khích với lựa chọn từ "khá". –

Trả lời

25

Mỗi double là 8 byte, vì vậy bạn đang cố gắng phân bổ một mảng duy nhất với chỉ hơn 5 GB. CLR có giới hạn cho mỗi đối tượng khoảng 2GB IIRC, ngay cả đối với CLR 64 bit. Nói cách khác, nó không phải là tổng số bộ nhớ có sẵn đó là vấn đề (mặc dù rõ ràng bạn sẽ có vấn đề nếu bạn không có đủ bộ nhớ), nhưng kích thước cho mỗi đối tượng.

Tôi đề nghị bạn chia thành các mảng nhỏ hơn, có lẽ đằng sau mặt tiền của một số mô tả. Tôi không tin rằng có bất kỳ cách nào để giải quyết giới hạn đó cho một mảng đơn lẻ.

EDIT: Bạn thể đi cho một mảng của mảng - aka một mảng lởm chởm:

double[][] array = new double[12000][]; 
for (int i = 0; i < array.Length; i++) 
{ 
    array[i] = new double[55000]; 
} 

rằng có thể chấp nhận được đối với bạn?

(Bạn không thể sử dụng một mảng hình chữ nhật (double[,]) như rằng sẽ có cùng một vấn đề cho mỗi đối tượng kích thước.)

+0

+1 để thực sự làm việc với kích thước. Tôi không nên lười biếng như vậy – Ian

+0

ok cảm ơn. vì vậy nó không thể sử dụng bộ nhớ ảo có thể nó? – cs0815

+1

Thay vì một mảng duy nhất của đôi, tôi nghĩ rằng ông có nghĩa là mảng 2D – bitxwise

0

Hoặc bạn đã hết bộ nhớ (đóng một số chương trình) hoặc bạn đang đạt đến giới hạn phân bổ bộ nhớ (khoảng 2Gb), bộ nhớ này cần phải là khối liền kề. Bạn có thể sử dụng một máy 64bit trong trường hợp bạn sẽ có nhiều bộ nhớ hơn hoặc tôi nghĩ rằng bạn có thể làm cho ứng dụng nhận biết địa chỉ lớn (googling sẽ cho bạn biết cách thực hiện điều này nếu có thể trong trường hợp này).

Hãy tin rằng bạn thêm nút chuyển/3 GB vào tệp Boot.ini để nhận biết địa chỉ lớn.

9

Vì bạn không thể tạo các đối tượng lớn hơn 2GB bạn có thể thử sử dụng MemoryMappedFile để làm việc với bộ nhớ của kích thước cần thiết.

 

var data = MemoryMappedFile.CreateNew("big data", 12000L * 55000L); 
var view = data.CreateViewAccessor(); 
var rnd = new Random(); 

for (var i = 0L; i < 12000L; ++i) 
{ 
    for (var j = 0L; j < 55000L; ++j) 
    { 
     var input = rnd.NextDouble(); 
     view.Write<double>(i * 55000L + j, ref input); 
    } 
} 
 
4

Cung cấp tổng bộ nhớ của bạn là đủ, bạn có thể ngăn Out of ngoại lệ bộ nhớ kết quả từ LOH phân mảnh bằng cách tạo ra một loạt các mảng nhỏ hơn, và gói chúng trong một đơn IList<T>, hoặc một số giao diện lập chỉ mục khác.

Dưới đây là một liên kết trong đó mô tả nó:

BigArray<T>, getting around the 2GB array size limit

Điểm Uy Tín: this post (C# chunked array).

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