2010-05-06 30 views
5

Tôi có một phần mã hoạt động trên các mảng lớn double (có chứa khoảng 6000 phần tử ít nhất) và thực hiện vài trăm lần (thường là 800).Rò rỉ bộ nhớ khi sử dụng mảng đôi

Khi tôi sử dụng vòng lặp tiêu chuẩn, như thế:

double[] singleRow = new double[6000]; 
int maxI = 800; 
for(int i=0; i<maxI; i++) 
{ 
singleRow = someObject.producesOutput(); 
//... 
// do something with singleRow 
// ... 
} 

Bộ nhớ sử dụng tăng khoảng 40MB (từ 40MB tại beggining của vòng lặp, đến 80MB ở cuối).

Khi tôi buộc sử dụng bộ thu gom rác để thực thi tại mỗi lần lặp lại, mức sử dụng bộ nhớ vẫn ở mức 40MB (mức tăng không đáng kể).

double[] singleRow = new double[6000]; 
int maxI = 800; 
for(int i=0; i<maxI; i++) 
{ 
singleRow = someObject.producesOutput(); 
//... 
// do something with singleRow 
// ... 
GC.Collect() 
} 

Nhưng thời gian thực hiện dài gấp 3 lần! (điều quan trọng)

Làm cách nào để buộc C# sử dụng cùng một vùng bộ nhớ thay vì cấp phát bộ nhớ mới? Lưu ý: Tôi có quyền truy cập vào mã số someObject lớp học, vì vậy nếu cần, tôi có thể thay đổi nó.

+1

Tôi muốn xem bạn làm gì với mảng sau khi bạn nhận được nó và cách productionOutput hoạt động, nếu có thể. –

Trả lời

7

Tại sao bạn chỉ định một số lớn, trống singleRow chỉ để ghi đè lên nó? Có lẽ bạn nên chuyển mảng vào để các giá trị của nó được sửa đổi tại chỗ. Điều này sẽ cho phép bạn sử dụng lại nó.

double[] singleRow = new double[6000]; 
int maxI = 800; 
for(int i=0; i<maxI; i++) 
{ 
    someObject.FillWithOutput(singleRow); 
    //... 
    // do something with singleRow 
    // ... 
} 

Nếu phương pháp đôi khi điền ít hơn 6000 phần tử, nó có thể đơn giản trả về số lần điền. Cách khác, bạn có thể sử dụng một số List<double>, điều này sẽ cho phép thay đổi kích thước.

+0

Có vẻ như giải pháp là đơn giản ..;) Cảm ơn! Nó hoạt động. – Gacek

+0

Rất vui được lời khuyên của chúng tôi. –

3

Hãy singleRow một tham số và vượt qua nó vào cuộc gọi đến producesOutput mỗi khi ...

Về cơ bản phương pháp producesOutput của bạn có lẽ là phân bổ một mảng mới mọi thời gian, và việc tái phân công singleRow chỉ đánh dấu sự cũ bộ nhớ là có sẵn để xóa, nhưng không chạy GC vì lý do hiệu suất.

+1

Không cần phải làm cho nó một ref nếu mảng có chiều dài cố định. –

+0

Đúng vậy. Cảm ơn bạn đã nhắc nhở :) –

+1

Có thể cho rằng, 'ref' sẽ không gây hại trực tiếp và sẽ thể hiện ý định sửa đổi tham số. Tuy nhiên, tôi không nghĩ đó là điều phải làm. –

0

Bạn sẽ không thích điều này, nhưng nếu bạn buộc GC bạn đang làm gì đó sai. Hãy nhớ rằng bộ nhớ có thể phát triển cho đến khi có áp lực để kích hoạt một GC - đây là một điều TỐT vì nó có nghĩa là GC không chạy cho đến khi nó phải.

Đây là một bài kiểm tra âm thầm, nhưng nó có thể làm sáng tỏ một số điều đang xảy ra. Bên trong FillWithOutput() nhận xét hầu hết các chức năng của nó. Sau đó chạy vòng lặp của bạn và đo lường memeory. Gia tăng un-comment ra miếng của nó cho đến khi bạn nhìn thấy một blip. Bây giờ bạn đang đến gần hơn với những gì đang gây ra 'rò rỉ'.

+0

Tôi nghĩ rằng nguồn gốc của "rò rỉ" là khá rõ ràng rồi. –