Trình biên dịch bộ nhớ Python nào được khuyến nghị? [đóng cửa]


668

Tôi muốn biết việc sử dụng bộ nhớ của ứng dụng Python của mình và đặc biệt muốn biết khối / phần hoặc đối tượng mã nào đang chiếm phần lớn bộ nhớ. Tìm kiếm của Google cho thấy một mục thương mại là Trình xác thực bộ nhớ Python (chỉ dành cho Windows).

Và những người nguồn mở là PySizerHeapy .

Tôi chưa từng thử ai, vì vậy tôi muốn biết ai là người cân nhắc tốt nhất:

  1. Cung cấp hầu hết các chi tiết.

  2. Tôi phải làm ít nhất hoặc không thay đổi mã của tôi.


2
Để tìm các nguồn rò rỉ, tôi khuyên bạn nên dùng objgraph.
pi.

9
@MikeiLL Có một nơi dành cho những câu hỏi như sau: Khuyến nghị phần mềm
Poik

2
Điều này thường xảy ra đủ để chúng ta có thể di chuyển một câu hỏi sang diễn đàn khác.
zabumba

Một mẹo: Nếu ai đó sử dụng gae đến và muốn kiểm tra việc sử dụng bộ nhớ - đó là một vấn đề đau đầu, bởi vì những công cụ đó không tạo ra gì hoặc sự kiện không bắt đầu. Nếu bạn muốn kiểm tra một cái gì đó nhỏ, hãy di chuyển chức năng mà bạn muốn kiểm tra để tách tệp và chạy tệp này một mình.
alexche8

4
Tôi khuyên dùng pympler
zzzeek

Câu trả lời:


286

Heapy khá đơn giản để sử dụng. Tại một số điểm trong mã của bạn, bạn phải viết như sau:

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

Điều này cung cấp cho bạn một số đầu ra như thế này:

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)

Bạn cũng có thể tìm ra nơi các đối tượng được tham chiếu và lấy số liệu thống kê về điều đó, nhưng bằng cách nào đó, các tài liệu trên đó hơi thưa thớt.

Có một trình duyệt đồ họa là tốt, được viết bằng Tk.


24
Nếu bạn đang dùng Python 2.7, bạn có thể cần phiên bản trung kế của nó: sourceforge.net/tracker/iêu ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder

27
Các tài liệu heapy là ... không tốt. Nhưng tôi thấy bài đăng trên blog này rất hữu ích để bắt đầu: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw

4
Lưu ý, heapy không bao gồm bộ nhớ được phân bổ trong phần mở rộng python. Nếu bất cứ ai đã xây dựng một cơ chế để có được nhiều thứ để bao gồm boost::pythoncác đối tượng, thật tuyệt khi thấy một số ví dụ!
amos

34
Kể từ 2014 / 07-06, guppy không hỗ trợ Python 3.
Quentin Pradet

5
Có một nhánh guppy hỗ trợ Python 3 được gọi là guppy3.
David Foster

383

Vì không ai đề cập đến nó nên tôi sẽ trỏ đến module_profiler mô-đun của tôi có khả năng in báo cáo từng dòng về việc sử dụng bộ nhớ và hoạt động trên Unix và Windows (cần psutil trên cái cuối cùng này). Đầu ra không thật chi tiết nhưng mục tiêu là cung cấp cho bạn cái nhìn tổng quan về nơi mã đang tiêu thụ nhiều bộ nhớ hơn và không phải là một phân tích toàn diện về các đối tượng được phân bổ.

Sau khi trang trí chức năng của bạn với @profilevà chạy mã của bạn bằng -m memory_profilercờ, nó sẽ in một báo cáo từng dòng như thế này:

Line #    Mem usage  Increment   Line Contents
==============================================
     3                           @profile
     4      5.97 MB    0.00 MB   def my_func():
     5     13.61 MB    7.64 MB       a = [1] * (10 ** 6)
     6    166.20 MB  152.59 MB       b = [2] * (2 * 10 ** 7)
     7     13.61 MB -152.59 MB       del b
     8     13.61 MB    0.00 MB       return a

1
Đối với usecase của tôi - một kịch bản xử lý hình ảnh đơn giản, không phải là một hệ thống phức tạp, tình cờ để lại một số con trỏ mở - đây là giải pháp tốt nhất. Rất đơn giản để thả vào và tìm hiểu những gì đang diễn ra, với gunk tối thiểu được thêm vào mã của bạn. Hoàn hảo để sửa lỗi nhanh và có lẽ cũng tuyệt vời cho các ứng dụng khác.
driftcatcher

10
Tôi thấy memory_profiler thực sự đơn giản và dễ sử dụng. Tôi muốn làm hồ sơ trên mỗi dòng và không phải mỗi đối tượng. Cảm ơn đã viết.
tommy.carstensen

1
@FabianPedregosa làm thế nào liều memory_profiler xử lý các vòng lặp, nó có thể xác định số vòng lặp lặp không?
Glen Fletcher

3
Nó xác định các vòng lặp chỉ ngầm định khi nó cố gắng báo cáo số lượng từng dòng và nó tìm thấy các dòng trùng lặp. Trong trường hợp đó, nó sẽ chỉ lấy tối đa của tất cả các lần lặp.
Fabian Pedregosa

1
@FabianPedregosa Có memory_profilerđệm đầu ra của nó không? Tôi có thể đang làm gì đó sai, nhưng có vẻ như thay vì đổ hồ sơ cho một chức năng khi hoàn thành, nó chờ kịch bản kết thúc.
Greenstick

80

Tôi đề nghị Dowser . Nó rất dễ cài đặt và bạn không cần thay đổi mã của mình. Bạn có thể xem số lượng đối tượng của từng loại thông qua thời gian, xem danh sách các đối tượng sống, xem tham chiếu đến các đối tượng sống, tất cả từ giao diện web đơn giản.

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.server.quickstart()
    cherrypy.engine.start(blocking=False)

Bạn nhập memdebug và gọi memdebug.start. Đó là tất cả.

Tôi chưa thử PySizer hoặc Heapy. Tôi sẽ đánh giá cao đánh giá của người khác.

CẬP NHẬT

Đoạn mã trên là dành cho CherryPy 2.X, CherryPy 3.Xcác server.quickstartphương pháp đã bị xoá và engine.startkhông lấy blockingcờ. Vì vậy, nếu bạn đang sử dụngCherryPy 3.X

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.engine.start()

3
Nhưng nó chỉ dành cho cherrypy, làm thế nào để sử dụng nó với một kịch bản tội lỗi?
Anurag Uniyal

13
Nó không dành cho CherryPy. Hãy nghĩ về CherryPy như một bộ công cụ GUI.
sanxiyn

1
fwiw, trang pysizer pysizer.8325.org dường như đề xuất heapy, mà nó nói là tương tự
Jacob Gabrielson

6
Có một cổng Dowser WSGI chung gọi là Dozer, bạn cũng có thể sử dụng với các máy chủ web khác: pypi.python.org/pypi/Dozer
Joe Shaw

2
cherrypy 3.1 đã gỡ bỏ cherrypy.server.quickstart (), vì vậy chỉ cần sử dụng cherrypy.engine.start ()
MatsLindh

66

Hãy xem xét thư viện objgraph (xemhttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks cho một trường hợp sử dụng ví dụ).


7
objgraph đã giúp tôi giải quyết vấn đề rò rỉ bộ nhớ mà tôi đang phải đối mặt ngày hôm nay. objgraph.show_growth () đặc biệt hữu ích
Ngure Nyaga

1
Tôi cũng vậy, thấy objgraph thực sự hữu ích. Bạn có thể làm những việc như objgraph.by_type('dict')để hiểu tất cả những dictvật thể bất ngờ đó đến từ đâu.
khủng long

18

Muppy là (chưa phải là một) Trình sử dụng bộ nhớ cho Python. Trọng tâm của bộ công cụ này được đặt vào việc xác định rò rỉ bộ nhớ.

Muppy cố gắng giúp các nhà phát triển nhận dạng rò rỉ bộ nhớ của các ứng dụng Python. Nó cho phép theo dõi việc sử dụng bộ nhớ trong thời gian chạy và xác định các đối tượng bị rò rỉ. Ngoài ra, các công cụ được cung cấp cho phép xác định vị trí nguồn của các đối tượng không được phát hành.


13

Tôi đang phát triển một trình lược tả bộ nhớ cho Python có tên là memprof:

http://jmdana.github.io/memprof/

Nó cho phép bạn ghi nhật ký và vẽ biểu đồ sử dụng bộ nhớ của các biến trong quá trình thực thi các phương thức được trang trí. Bạn chỉ cần nhập thư viện bằng cách sử dụng:

from memprof import memprof

Và trang trí phương pháp của bạn bằng cách sử dụng:

@memprof

Đây là một ví dụ về cách các ô trông như thế nào:

nhập mô tả hình ảnh ở đây

Dự án được lưu trữ trong GitHub:

https://github.com/jmdana/memprof


3
Làm thế nào để tôi sử dụng nó? A, b, c là gì?
tommy.carstensen

@ tommy.carstensen a, bclà tên của các biến. Bạn có thể tìm tài liệu tại github.com/jmdana/memprof . Nếu bạn có bất kỳ câu hỏi nào, vui lòng gửi một vấn đề trong github hoặc gửi email đến danh sách gửi thư có thể tìm thấy trong tài liệu.
jmdana

12

Tôi thấy meliae có nhiều chức năng hơn Heapy hoặc PySizer. Nếu bạn tình cờ đang chạy một ứng dụng web wsgi, thì Dozer là một trình bao bọc phần mềm trung gian tuyệt vời của Dowser


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.