2010-12-14 27 views
21

Tôi đang xây dựng một từ điển dữ liệu lớn từ một tập hợp các tệp văn bản. Khi tôi đọc trong các dòng và xử lý chúng, tôi append(dataline) vào một danh sách.Tại sao Python `Lỗi bộ nhớ` với danh sách` append() `nhiều RAM còn lại

Tại một số điểm, append() tạo ra ngoại lệ Memory Error. Tuy nhiên, xem chương trình chạy trong Trình quản lý tác vụ Windows, tại thời điểm xảy ra sự cố, tôi thấy 4,3 GB khả dụng và 1,1 GB miễn phí.

Vì vậy, tôi không hiểu lý do ngoại lệ.

Phiên bản Python là 2.6.6. Tôi đoán, lý do duy nhất là nó không thể sử dụng nhiều RAM sẵn có hơn. Nếu điều này là như vậy, có thể tăng phân bổ không?

+1

Hãy thử sử dụng bản dựng Python 64 bit. Mặc dù nếu bạn đang sử dụng bất kỳ mô-đun mở rộng nào, thì chúng cũng sẽ cần phải được xây dựng 64 bit. –

+0

Bạn có thể in chuỗi ngoại lệ 'MemoryError' không? Điều đó sẽ cung cấp cho chúng tôi thêm thông tin. – chrisaycock

+0

Bạn có đang thêm trước hoặc sau khi xử lý các dòng không? – nmichaels

Trả lời

27

Nếu bạn đang sử dụng bản dựng Python 32 bit, bạn có thể muốn dùng thử phiên bản 64 bit.

Có thể quy trình xử lý tối đa 4GB RAM sử dụng địa chỉ 32 bit, nhưng thông thường (tùy thuộc vào hệ điều hành), một quy trình nhận được ít hơn nhiều. Có vẻ như quá trình Python của bạn có thể đạt đến giới hạn này. Địa chỉ 64 bit loại bỏ giới hạn này.

chỉnh sửa Vì bạn đang hỏi về Windows, trang sau có liên quan: Memory Limits for Windows Releases. Như bạn có thể thấy, giới hạn cho mỗi quy trình 32 bit là 2, 3 hoặc 4GB tùy thuộc vào phiên bản và cấu hình hệ điều hành.

+0

Có, 32 bit. Bất kỳ cách nào để kiểm soát số tiền được phân bổ? Hoặc để xem có bao nhiêu được phân bổ? Tôi muốn xác minh xem chúng tôi có đạt tới giới hạn hay không. BTW quá trình được liệt kê là sử dụng 1,9 GB trong cửa sổ Task Manager khi nó bị treo. – Pete

+0

@Pete Bạn sẽ có thể thấy điều này trong Trình quản lý tác vụ: http://upload.wikimedia.org/wikipedia/en/6/6b/System_idle_process.png (trong "Sử dụng Mem"). – NPE

+0

Tôi muốn nói, xem giới hạn phân bổ là gì hoặc thay đổi nó, để xác minh rằng chúng tôi đã hết bộ nhớ, thay vì giả sử 1.9GB, phân bổ hiện tại, là giới hạn – Pete

4

Nếu bạn đang mở để tái cấu trúc mã thay vì ném thêm bộ nhớ vào nó, bạn có thể để có được bằng với điều này:

data = (processraw(raw) for raw in lines) 

nơi lines là hoặc là một danh sách các dòng hoặc file.xreadlines() hoặc tương tự .

3

Tôi đã gặp sự cố tương tự khi sử dụng phiên bản 32 bit của python trong môi trường cửa sổ 64 bit. Tôi đã thử phiên bản cửa sổ 64-bit của python và rất nhanh chóng gặp rắc rối với các thư viện Scipy được biên dịch cho các cửa sổ 64-bit.

Các giải pháp hoàn toàn miễn phí mà tôi thực hiện là

1) Cài đặt VirtualBox
2) Cài đặt CentOS 5.6 trên VM
3) Lấy phân phối Enthought Python (miễn phí 64 bit Linux Version).

Bây giờ tất cả mã python phụ thuộc Numpy, Scipy và Matplotlib của tôi có thể sử dụng nhiều bộ nhớ như tôi có Ram và trao đổi Linux có sẵn.

0

Như đã được đề cập, bạn sẽ cần một bit python64 (của phiên bản 64 bit của cửa sổ).

Lưu ý rằng bạn có thể sẽ phải đối mặt với rất nhiều xung đột và sự cố với một số gói cơ bản mà bạn có thể muốn làm việc. để tránh vấn đề này, tôi khuyên bạn nên Anaconda từ Continuum Analytics. Tôi khuyên bạn nên nhìn vào nó :)

3

Tôi đã gặp phải sự cố tương tự khi đánh giá biểu thức có chứa các mảng numpy lớn (thực tế, một mảng đã thưa thớt). Tôi đã làm điều này trên một máy tính với 64GB bộ nhớ, trong đó chỉ có khoảng 8GB đã được sử dụng, vì vậy đã rất ngạc nhiên khi nhận được MemoryError.

Hóa ra vấn đề của tôi là phát sóng hình dạng mảng: Tôi đã vô tình nhân đôi một chiều không gian lớn.

Nó đã đi một cái gì đó như thế này:

  • tôi đã vượt qua một mảng với hình dạng (286577, 1) nơi tôi đã mong (286577).
  • Điều này đã bị trừ khỏi một mảng có hình dạng (286577, 130).
  • Vì tôi đã mong đợi (286577), tôi đã áp dụng [:,newaxis] trong biểu thức để mang nó đến (286577,1) để nó sẽ được phát sóng tới (286577,130).
  • Khi tôi thông qua hình dạng (286577,1) tuy nhiên, [:,newaxis] hình dạng sản xuất (286577,1,1) và cả hai mảng đều được phát sóng thành hình dạng (286577,286577,130) ... của đôi. Với hai mảng như vậy, khoảng 80GB!
Các vấn đề liên quan