2010-11-14 16 views
11

Tôi đang thực hiện một số tính toán nặng với Python (sử dụng OpenCV và Numpy) và cuối cùng, tôi sẽ sử dụng rất nhiều bộ nhớ (> 1GB) theo đó tất cả các refs nên được đi và tôi chỉ có kết quả cuối cùng (mà không nên nhiều hơn một vài MB).Python: số liệu thống kê sử dụng bộ nhớ trên mỗi loại đối tượng (hoặc dòng mã nguồn)

Để gỡ lỗi này, sẽ tốt hơn nếu tôi có thể nhận được một số số liệu thống kê bằng cách nào đó cho tôi biết có bao nhiêu trường hợp đối tượng có loại nào, được sắp xếp theo tổng dung lượng bộ nhớ của chúng (mỗi lớp đối tượng).

Hoặc thậm chí đẹp hơn: Không phải trên mỗi lớp đối tượng mà trên mỗi dòng mã nguồn nơi đối tượng được tạo (theo đó tôi đoán thông tin này không có sẵn trừ khi tôi kích hoạt một số gỡ lỗi bằng Python sẽ làm cho việc tính toán quá chậm, vì vậy tôi không chắc chắn nếu điều đó sẽ hữu ích).

Tôi có thể lấy một số số liệu thống kê như thế này bằng cách nào đó không? Hoặc làm thế nào tôi sẽ gỡ lỗi này?


Một số đã missunderstood tôi: Tôi chỉcần phải biết làm thế nào để gỡ lỗi sử dụng bộ nhớ. Thời gian xử lý/chạy là hoàn hảo.

+0

Đối với người mới bắt đầu, xem http://docs.python.org/library/profile.html –

+0

này không trả lời câu hỏi của bạn, nhưng nhìn vào \ _ \ _ khe \ _ \ _ để giảm tiêu thụ bộ nhớ rất nhiều. –

+0

@Rafe: Điều này dường như chỉ là về thời gian chạy chứ không phải về việc sử dụng bộ nhớ, phải không? – Albert

Trả lời

8

Tôi nghĩ rằng bạn đang tìm kiếm một trình biên dịch python;

bạn có một bó của họ mà bạn có thể sử dụng, như Heapy, profile or cprofile, Pysize ...

ví dụ sử dụng Heapy:

bạn phải bao gồm đoạn này ở đâu đó trong mã của bạn:

from guppy import hpy 
h = hpy() 
print h.heap() 

và nó sẽ cung cấp cho bạn như đầu ra:

Partition of a set of 132527 objects. Total size = 8301532 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
0 35144 27 2140412 26 2140412 26 str 
1 38397 29 1309020 16 3449432 42 tuple 
2 530 0 739856 9 4189288 50 dict (no owner) 

ví dụ với cProfile:

bạn có thể chạy nó như thế này:

python -m cProfile script.py 

Output:

  5 function calls in 0.000 CPU seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.000 0.000 <string>:1(<module>) 
     1 0.000 0.000 0.000 0.000 myscript.py:1(<module>) 
     1 0.000 0.000 0.000 0.000 {execfile} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
     1 0.000 0.000 0.000 0.000 {range} 

Bạn cũng có thể sử dụng gc module để biết tại sao python không giải phóng bộ nhớ của bạn, và yêu cầu anh ta giải phóng bộ nhớ bằng cách sử dụng gc.collect().

Bằng cách này, bạn đã xem numpy, tôi nghĩ nó phù hợp hơn nếu bạn đang tính toán nặng như bạn đã nói.

+2

Tôi hoàn toàn không thấy cách tôi có thể lấy số liệu thống kê bộ nhớ ra khỏi cProfile. Bạn có thể giải thích? – Albert

+0

Heapy có vẻ hữu ích hơn từ những gì nó hiển thị. Tuy nhiên, nó dường như không cho đầu ra chính xác. Nó nói rằng tổng kích thước là khoảng 8MB. Nhưng quá trình này mất khoảng> 1GB. – Albert

+0

Tôi đã sử dụng các công cụ trong objgraph (được mô tả [ở đây] (http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks)) và nó cho tôi kết quả tương tự. Nhưng tôi tự hỏi tại sao nó không hiển thị bất kỳ tham chiếu 'str' nào. Tuy nhiên, cả hai không thể hiện được phần lớn bộ nhớ thực sự là (khoảng 99% bộ nhớ thực bị thiếu trong đầu ra). Có lẽ nó là một rò rỉ bộ nhớ trong một trong các thư viện bên ngoài như OpenCV hoặc Numpy? – Albert

6

Ok, tôi đã săn lùng nó. Vì không có bản ghi nhớ Python nào cung cấp bất kỳ đầu ra hữu ích nào (vì chúng không thể tìm thấy bộ nhớ), tôi khá chắc chắn rằng một số libs bên ngoài (OpenCV) là nguồn của rò rỉ mem.

Và tôi có thể tái tạo các rò rỉ mem với mã đơn giản này:

import cv 
while True: cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1) 

Một số các nguồn lực khác cho Python mem gỡ lỗi đó khá thú vị (không giúp trong trường hợp đó nhưng có thể hữu ích cho những người khác):

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