2012-08-16 19 views
6

Sau khi tôi nâng cấp lên DotNet 4.5, một truy vấn bắt đầu cho tôi OutOfMemoryExceptions.Tại sao OutOfMemoryException bị ném trong khi sử dụng PLINQ Take()?

Các (cất) truy vấn là:

var tests = new int[]{} 
    .AsParallel() 
    .GroupBy(_ => _) 
    .Take(int.MaxValue) 
    .ToArray(); 

Tôi gửi bài này cho bất cứ ai có cùng một vấn đề. Tôi sẽ trả lời dưới đây.

+2

Bạn có đang chạy ở mức 32 bit hoặc 64 bit không? – Oded

+0

Quy trình 32 bit. –

+0

Tôi đã sử dụng loại mã này bên trong một hàm nhận được thông số có số lượng các phần tử cần trả về. Thông qua int.MaxValue (có một quá tải mà đã làm điều đó) về cơ bản có nghĩa là 'mất tất cả mọi thứ'. –

Trả lời

7

Dường như đây là thay đổi trong khuôn khổ.

Toán tử Take() được triển khai trong lớp nội bộ TakeOrSkipQueryOperator. Có một nhánh trong mã đi qua một hàm WrapHelper() tạo ra một cá thể FixedMapHeap mà lần lượt tạo ra một mảng các phần tử Key có kích thước được truyền ban đầu tới Take() (sẽ là một mảng 8Gb trong ví dụ đã cho)).

+0

Ok. Nhưng làm thế nào để sửa chữa nó? – Steven

+1

@Steven Đặt giá trị 'Take' mà bạn có đủ bộ nhớ để lưu trữ nhiều kết quả. (Hoặc có nhiều bộ nhớ hơn.) – Servy

+3

Âm thanh giống như tối ưu hóa hợp lý nhiều thời gian - nên cho phép song song tốt hơn trong nhiều trường hợp vì các luồng khác nhau có thể ghi vào các phần khác nhau của vùng đó mà không có nguy cơ gây trở ngại cho nhau. Phía dưới trong trường hợp này là rõ ràng mặc dù. –

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