แนะนำหน่วยความจำ Python ใด? [ปิด]


670

ฉันต้องการทราบการใช้หน่วยความจำของแอปพลิเคชั่น Python ของฉันและต้องการทราบว่าการบล็อกโค้ด / ส่วนหรือวัตถุใดที่ใช้หน่วยความจำมากที่สุด การค้นหาของ Google แสดงโฆษณาหนึ่งคือPython Memory Validator (Windows เท่านั้น)

และคนที่มาเปิดPySizerและHeapy

ฉันไม่ได้ลองใครเลยฉันอยากรู้ว่าอันไหนดีที่สุดในการพิจารณา:

  1. ให้รายละเอียดมากที่สุด

  2. ฉันต้องทำอย่างน้อยหรือไม่มีการเปลี่ยนแปลงรหัสของฉัน


2
สำหรับการค้นหาแหล่งที่มาของการรั่วไหลฉันแนะนำ objgraph
ปี่

9
@MikeiLL มีสถานที่สำหรับคำถามเช่นนี้: คำแนะนำซอฟต์แวร์
Poik

2
สิ่งนี้เกิดขึ้นบ่อยครั้งมากพอที่เราจะสามารถย้ายคำถามหนึ่งไปยังฟอรัมอื่นแทน
zabumba

หนึ่งคำแนะนำ: ถ้ามีคนใช้ gae และต้องการตรวจสอบการใช้หน่วยความจำ - มันปวดหัวมากเพราะเครื่องมือเหล่านั้นไม่ส่งสัญญาณอะไรเลยหรือเหตุการณ์ไม่เริ่มต้น หากคุณต้องการทดสอบสิ่งเล็ก ๆ ให้ย้ายฟังก์ชั่นที่คุณต้องการทดสอบเพื่อแยกไฟล์และเรียกใช้ไฟล์นี้เพียงอย่างเดียว
alexche8

4
ฉันแนะนำpympler
zzzeek

คำตอบ:


288

Heapyนั้นใช้ง่ายมาก ในบางจุดของรหัสคุณต้องเขียนสิ่งต่อไปนี้:

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

สิ่งนี้ให้ผลลัพธ์บางอย่างเช่นนี้:

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)

นอกจากนี้คุณยังสามารถค้นหาว่าวัตถุใดถูกอ้างอิงและรับสถิติเกี่ยวกับเรื่องนั้น แต่อย่างใดเอกสารที่ค่อนข้างเบาบาง

มีเบราว์เซอร์กราฟิกเช่นกันเขียนเป็น Tk


24
หากคุณใช้ Python 2.7 คุณอาจต้องใช้รุ่น trunk: sourceforge.net/tracker/… ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder

27
heapy docs นั้น ... ไม่ดี แต่ฉันพบว่าการโพสต์บล็อกนี้มีประโยชน์มากสำหรับการเริ่มต้น: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw

4
หมายเหตุ heapy ไม่รวมหน่วยความจำที่จัดสรรในส่วนขยายหลาม หากใครก็ตามหาวิธีที่จะทำให้ heapy รวมboost::pythonวัตถุมันคงจะดีถ้าได้เห็นตัวอย่าง!
amos

34
ตั้งแต่วันที่ 2014-07-06 ปลาหางนกยูงไม่สนับสนุน Python 3
Quentin Pradet

5
มีส้อมของปลาหางนกยูงที่รองรับ Python 3 เรียกว่า guppy3
David Foster

385

เนื่องจากไม่มีใครพูดถึงมันฉันจะชี้ไปที่โมดูลmemory_profilerซึ่งสามารถพิมพ์รายงานการใช้หน่วยความจำแบบทีละบรรทัดและทำงานบน Unix และ Windows (ต้องการ psutil ในอันสุดท้าย) ผลลัพธ์ไม่ได้มีรายละเอียดมากนัก แต่เป้าหมายคือเพื่อให้ภาพรวมของรหัสที่ใช้หน่วยความจำมากขึ้นและไม่ได้วิเคราะห์อย่างละเอียดเกี่ยวกับวัตถุที่จัดสรร

หลังจากตกแต่งฟังก์ชั่นของคุณด้วย@profileและเรียกใช้รหัสของคุณด้วยการ-m memory_profilerตั้งค่าสถานะมันจะพิมพ์รายงานทีละบรรทัดดังนี้:

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
สำหรับ usecase ของฉัน - สคริปต์การจัดการรูปภาพอย่างง่ายไม่ใช่ระบบที่ซับซ้อนซึ่งเกิดขึ้นเพื่อปล่อยเคอร์เซอร์ไว้ - นี่เป็นทางออกที่ดีที่สุด ง่ายมากที่จะเข้าและรู้ว่าเกิดอะไรขึ้นโดยเพิ่ม gunk น้อยที่สุดในโค้ด เหมาะสำหรับการแก้ไขอย่างรวดเร็วและอาจยอดเยี่ยมสำหรับแอปพลิเคชันอื่นเช่นกัน
Driftcatcher

10
ฉันพบ memory_profiler ว่าใช้ง่ายและใช้งานง่าย ฉันต้องการทำโปรไฟล์ต่อบรรทัดไม่ใช่ต่อวัตถุ ขอบคุณสำหรับการเขียน
tommy.carstensen

1
@FabianPedregosa ขนาดหน่วยความจำ memory_profiler จัดการลูปมันสามารถระบุหมายเลขวนซ้ำวนซ้ำได้หรือไม่
เกลนเฟลตเชอร์

3
มันระบุลูปโดยปริยายเฉพาะเมื่อพยายามรายงานจำนวนบรรทัดต่อบรรทัดและพบว่ามีการทำซ้ำบรรทัด ในกรณีนี้มันจะทำซ้ำได้สูงสุด
Fabian Pedregosa

1
@FabianPedregosa memory_profilerบัฟเฟอร์เอาต์พุตของมันหรือไม่? ฉันอาจจะทำสิ่งผิดปกติ แต่ดูเหมือนว่าแทนที่จะทิ้งโปรไฟล์สำหรับฟังก์ชั่นเมื่อมันเสร็จสมบูรณ์ก็จะรอสคริปต์ที่จะสิ้นสุด
Greenstick

80

ผมขอแนะนำให้Dowser มันง่ายมากในการติดตั้งและคุณต้องไม่มีการเปลี่ยนแปลงรหัสของคุณ คุณสามารถดูจำนวนวัตถุของแต่ละประเภทผ่านเวลาดูรายการวัตถุสดดูการอ้างอิงไปยังวัตถุสดทั้งหมดได้จากเว็บอินเตอร์เฟสที่เรียบง่าย

# 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)

คุณนำเข้า memdebug และโทร memdebug.start นั่นคือทั้งหมดที่

ฉันไม่ได้ลอง PySizer หรือ Heapy ฉันขอขอบคุณบทวิจารณ์ของผู้อื่น

UPDATE

รหัสข้างต้นสำหรับCherryPy 2.X, วิธีการได้ถูกถอดออกและไม่ได้ใช้ธง ดังนั้นหากคุณกำลังใช้CherryPy 3.Xserver.quickstartengine.startblockingCherryPy 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
แต่มันมีไว้สำหรับ cherrypy เท่านั้นจะใช้งานอย่างไรกับสคริปต์ sinple?
Anurag Uniyal

13
มันไม่ได้สำหรับ CherryPy คิดว่า CherryPy เป็นชุดเครื่องมือ GUI
sanxiyn

1
FWIW หน้า pysizer pysizer.8325.orgดูเหมือนว่าจะแนะนำ heapy ซึ่งมันบอกว่ามีความคล้ายคลึง
จาค็อบ Gabrielson

6
มีพอร์ต WSGI ทั่วไปของ Dowser เรียกว่า Dozer ซึ่งคุณสามารถใช้กับเว็บเซิร์ฟเวอร์อื่น ๆ ได้เช่นกัน: pypi.python.org/pypi/Dozer
Joe Shaw

2
cherrypy 3.1 ลบ cherrypy.server.quickstart () ดังนั้นเพียงใช้ cherrypy.engine.start ()
MatsLindh

66

พิจารณาไลบรารีobjgraph (ดูhttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaksสำหรับกรณีการใช้งานตัวอย่าง)


7
objgraph ช่วยฉันแก้ปัญหาการรั่วไหลของหน่วยความจำที่ฉันกำลังเผชิญ objgraph.show_growth () มีประโยชน์อย่างยิ่ง
Ngure Nyaga

1
ฉันก็พบว่า objgraph มีประโยชน์จริงๆ คุณสามารถทำสิ่งต่าง ๆobjgraph.by_type('dict')เพื่อทำความเข้าใจว่าdictวัตถุที่ไม่คาดคิดมาจากไหน
dino

18

Muppyคือ (อีกอัน) Memory Profiler สำหรับ Python จุดเน้นของชุดเครื่องมือนี้มีการระบุการรั่วไหลของหน่วยความจำ

Muppy พยายามช่วยนักพัฒนาในการจำการรั่วไหลของแอพพลิเคชั่น Python ช่วยให้สามารถติดตามการใช้งานหน่วยความจำระหว่างรันไทม์และการระบุวัตถุที่รั่ว นอกจากนี้มีการจัดเตรียมเครื่องมือที่อนุญาตให้ค้นหาตำแหน่งของวัตถุที่ไม่ได้วางจำหน่าย


13

ฉันกำลังพัฒนา profiler หน่วยความจำสำหรับ Python ชื่อ memprof:

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

จะช่วยให้คุณสามารถบันทึกและลงจุดการใช้งานหน่วยความจำของตัวแปรของคุณในระหว่างการดำเนินการตามวิธีการตกแต่ง คุณเพียงแค่ต้องนำเข้าห้องสมุดโดยใช้:

from memprof import memprof

และตกแต่งวิธีการของคุณโดยใช้:

@memprof

นี่คือตัวอย่างเกี่ยวกับลักษณะของแปลง:

ป้อนคำอธิบายรูปภาพที่นี่

โครงการโฮสต์ใน GitHub:

https://github.com/jmdana/memprof


3
ฉันจะใช้มันได้อย่างไร a, b, c คืออะไร
tommy.carstensen

@ tommy.carstensen a, bและcเป็นชื่อของตัวแปร คุณสามารถค้นหาเอกสารที่github.com/jmdana/memprof หากคุณมีคำถามใด ๆ โปรดอย่าลังเลที่จะส่งปัญหาใน GitHub หรือส่งอีเมลไปที่รายชื่อผู้รับจดหมายที่สามารถพบได้ในเอกสารประกอบ
jmdana

12

ฉันพบว่าMeliaeนั้นทำงานได้ดีกว่า Heapy หรือ PySizer หากคุณกำลังใช้งานเว็บแอพพลิเคชั่น wsgi อยู่Dozerเป็นมิดเดิ้ลแวร์ห่อหุ้มของ Dowser


8

ลองใช้โครงการ pytracemallocซึ่งจัดเตรียมการใช้หน่วยความจำต่อหมายเลขบรรทัด Python

แก้ไข (2014/04): ตอนนี้มี Qt GUI เพื่อวิเคราะห์ภาพรวม


4
tracemallocตอนนี้เป็นส่วนหนึ่งของไลบรารีมาตรฐานหลาม ดูdocs.python.org/3/library/tracemalloc.html
Dan Milon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.