Last chance! 50% off DataCamp Premium
Sale ends in
Aplikasi Python, terutama yang menangani kumpulan data besar atau komputasi kompleks, dapat mengonsumsi memori berlebihan, yang mengakibatkan perlambatan, crash, atau galat kehabisan memori. Profiling memori adalah teknik yang memungkinkan Anda menganalisis penggunaan memori kode Python, mengidentifikasi kebocoran dan hambatan memori, serta mengoptimalkan konsumsi memori untuk meningkatkan performa dan stabilitas.
Dalam tutorial ini, kita akan membahas profiling memori, alat yang tersedia, dan contoh praktis cara menggunakan alat-alat tersebut untuk memprofilkan kode Python Anda.
Profiling memori adalah teknik memantau dan mengevaluasi pemanfaatan memori suatu program saat berjalan. Metode ini membantu pengembang menemukan kebocoran memori, mengoptimalkan pemanfaatan memori, dan memahami pola konsumsi memori programnya. Profiling memori penting untuk mencegah aplikasi menggunakan memori lebih dari yang diperlukan sehingga menyebabkan performa lambat atau crash.
Profiling memori menawarkan beberapa keuntungan utama yang penting untuk menjaga aplikasi tetap efisien dan andal:
Mari jelajahi beberapa alat profiling memori populer, meliputi fitur, instalasi, dan penggunaannya. Secara khusus, kita akan melihat alat seperti memory_profiler untuk analisis memori per baris, tracemalloc untuk mengambil dan membandingkan snapshot memori, dan objgraph untuk memvisualisasikan relasi objek.
memory_profiler adalah alat yang kuat di Python yang memberikan wawasan mendetail tentang penggunaan memori kode Anda. Alat ini bekerja dengan memberikan rincian granular, baris demi baris, tentang penggunaan memori, yang berguna untuk menelusuri baris kode yang tepat penyebab konsumsi memori tinggi. Dengan memahami penggunaan memori pada tingkat detail ini, pengembang dapat mengambil keputusan yang tepat tentang area mana yang perlu diprioritaskan untuk dioptimalkan.
Untuk memasang memory_profiler dan paket tambahan yang diperlukan, ikuti langkah-langkah berikut:
Perintah berikut memasang paket memory_profiler:
pip install memory_profiler
Jika Anda ingin memvisualisasikan penggunaan memori dengan plot, Anda dapat memasang matplotlib dengan menjalankan:
pip install matplotlib
Untuk menggunakan memory_profiler, ikuti langkah-langkah berikut:
Kita tambahkan dekorator pada fungsi yang ingin diprofilkan.
Buka skrip Python Anda di editor teks atau IDE.
Impor dekorator profile dari memory_profiler dan terapkan pada fungsi yang ingin Anda profilkan.
Berikut contoh skrip:
from memory_profiler import profile
@profile
def allocate_memory():
# Allocate a list with a range of numbers
a = [i for i in range(10000)]
# Allocate another list with squares of numbers
b = [i ** 2 for i in range(10000)]
return a, b
if __name__ == "__main__":
allocate_memory()
Saya mengimpor dekorator profile dari paket memory_profiler di sini. Dekorator ini akan membantu kita memantau penggunaan memori fungsi yang didekorasi.
from memory_profiler import profile
Saya menerapkan dekorator @profile pada fungsi allocate_memory(). Ini berarti saat allocate_memory() dieksekusi, memory_profiler akan melacak penggunaan memorinya dan memberikan laporan terperinci.
@profile
Di dalam fungsi allocate_memory(), saya membuat dua list. List pertama berisi angka dari 0 hingga 9999; list kedua berisi kuadrat angka dari 0 hingga 9999.
a = [i for i in range(10000)] # List of numbers from 0 to 9999
b = [i**2 for i in range(10000)] # List of squares of numbers from 0 to 9999
Blok berikut memastikan bahwa fungsi allocate_memory() hanya dipanggil ketika skrip dijalankan langsung, bukan saat diimpor sebagai modul. Ketika Anda menjalankan skrip ini, memory_profiler akan menampilkan penggunaan memori fungsi allocate_memory(), sehingga Anda dapat melihat berapa banyak memori yang digunakan saat membuat dua list, a dan b.
if __name__ == "__main__":
allocate_memory()
Di terminal atau command prompt Anda, arahkan ke direktori tempat skrip Anda berada. Jalankan skrip Anda dengan opsi -m memory_profiler.
-m memory_profiler your_script.py

Penggunaan memori untuk setiap baris kode. Gambar oleh Penulis.
Pada grafik di atas, kita dapat melihat penggunaan memori tiap baris kode dan kenaikannya untuk setiap baris. Grafik di bawah menunjukkan secara lebih rinci bagaimana setiap baris menggunakan memori dan bagaimana meningkat di setiap iterasi.

Penggunaan memori dari waktu ke waktu. Gambar oleh Penulis.
tracemalloc adalah modul bawaan Python yang kuat untuk melacak alokasi dan dealokasi memori. Memahami bagaimana aplikasi Anda menggunakan memori sangat penting untuk mengoptimalkan performa dan mengidentifikasi kebocoran memori. Tracemalloc menyediakan antarmuka yang mudah digunakan untuk menangkap dan menganalisis snapshot penggunaan memori, sehingga menjadi alat yang sangat berharga bagi setiap pengembang Python.
Mari kita tinjau bagaimana tracemalloc mengambil snapshot penggunaan memori, membandingkan snapshot tersebut untuk mengidentifikasi kebocoran memori, lalu menganalisis konsumen memori teratas
tracemalloc memungkinkan Anda mengambil snapshot penggunaan memori pada titik tertentu dalam program. Snapshot menangkap status alokasi memori, memberikan tampilan terperinci tentang lokasi penggunaan memori.
Berikut cara mengambil snapshot dengan tracemalloc:
import tracemalloc
# Start tracing memory allocations
tracemalloc.start()
# Code block for which memory usage is to be tracked
def allocate_memory():
a = [i for i in range(10000)] # List of numbers from 0 to 9999
b = [i**2 for i in range(10000)] # List of squares of numbers from 0 to 9999
return a, b
# Keep the allocated lists in scope
allocated_lists = allocate_memory()
# Take a snapshot
snapshot = tracemalloc.take_snapshot()
# Stop tracing memory allocations
tracemalloc.stop()
# Analyze the snapshot to see memory usage
top_stats = snapshot.statistics('lineno')
# Write the memory usage data to a text file
with open('memory_usage.txt', 'w') as f:
f.write("[ Top 10 memory consumers ]\n")
for stat in top_stats[:10]:
f.write(f"{stat}\n")
# Detailed traceback for the top memory consumer
f.write("\n[ Detailed traceback for the top memory consumer ]\n")
for stat in top_stats[:1]:
f.write('\n'.join(stat.traceback.format()) + '\n')
print("Memory usage details saved to 'memory_usage.txt'")
Saya melacak dan memeriksa penggunaan memori dalam aplikasi Python menggunakan modul tracemalloc. Dengan mengambil snapshot alokasi memori dan melihat konsumen memori teratas, saya menentukan bagian kode mana yang menggunakan memori paling besar. Analisis ini kemudian saya simpan dalam berkas teks untuk ditinjau lebih lanjut.
Salah satu fitur terkuat tracemalloc adalah kemampuan membandingkan snapshot yang diambil pada titik berbeda dalam program untuk mengidentifikasi kebocoran memori. Dengan menganalisis perbedaan antar snapshot, Anda dapat menemukan di mana memori tambahan dialokasikan dan tidak dilepas.
Berikut cara membandingkan snapshot:
import tracemalloc
# Start tracing memory allocations
tracemalloc.start()
# Function to allocate memory
def allocate_memory():
a = [i for i in range(10000)] # List of numbers from 0 to 9999
b = [i**2 for i in range(10000)] # List of squares of numbers from 0 to 9999
return a, b
# Initial memory usage snapshot
snapshot1 = tracemalloc.take_snapshot()
# Perform memory allocations
allocated_lists = allocate_memory()
# Memory usage snapshot after allocations
snapshot2 = tracemalloc.take_snapshot()
# Further memory allocations (simulate more work to find potential leaks)
allocated_lists += allocate_memory()
# Memory usage snapshot after additional allocations
snapshot3 = tracemalloc.take_snapshot()
# Stop tracing memory allocations
tracemalloc.stop()
# Compare the snapshots
stats1_vs_2 = snapshot2.compare_to(snapshot1, 'lineno')
stats2_vs_3 = snapshot3.compare_to(snapshot2, 'lineno')
# Save the comparison results to a text file
with open('memory_leak_analysis.txt', 'w') as f:
f.write("[ Memory usage increase from snapshot 1 to snapshot 2 ]\n")
for stat in stats1_vs_2[:10]:
f.write(f"{stat}\n")
f.write("\n[ Memory usage increase from snapshot 2 to snapshot 3 ]\n")
for stat in stats2_vs_3[:10]:
f.write(f"{stat}\n")
# Detailed traceback for the top memory consumers
f.write("\n[ Detailed traceback for the top memory consumers ]\n")
for stat in stats2_vs_3[:1]:
f.write('\n'.join(stat.traceback.format()) + '\n')
print("Memory leak analysis saved to 'memory_leak_analysis.txt'")

Dari snapshot 1 ke snapshot 2, kita melihat bahwa pembuatan list a dan b menjadi penyebab utama lonjakan penggunaan memori. Beralih dari snapshot 2 ke snapshot 3, kita juga melihat bahwa lebih banyak alokasi list a dan b meningkatkan pemanfaatan memori.
Dengan membandingkan snapshot ini, kita menemukan bahwa penyebab utama meningkatnya penggunaan memori adalah alokasi berulang list besar. Jika alokasi ini tidak diperlukan dalam aplikasi nyata, hal tersebut dapat mengindikasikan kebocoran memori. Traceback yang komprehensif dapat mengidentifikasi baris kode tepat yang menyebabkan alokasi ini.
tracemalloc juga menyediakan alat untuk menganalisis konsumen memori teratas dalam aplikasi Anda. Ini membantu Anda memfokuskan optimasi pada bagian kode yang paling banyak menggunakan memori.
Berikut cara menganalisis konsumen memori teratas:
import tracemalloc
# Start tracing memory allocations
tracemalloc.start()
# Code block for which memory usage is to be tracked
def allocate_memory():
a = [i for i in range(10000)]
b = [i**2 for i in range(10000)]
allocate_memory()
# Take a snapshot
snapshot = tracemalloc.take_snapshot()
# Analyze top memory consumers
top_stats = snapshot.statistics('lineno')
print("[ Top 10 memory consumers ]")
for stat in top_stats[:10]:
print(stat)
# Stop tracing memory allocations
tracemalloc.stop()
Dalam contoh ini, setelah mengambil snapshot, saya menggunakan snapshot.statistics('lineno') untuk mendapatkan statistik penggunaan memori yang dikelompokkan berdasarkan nomor baris. Keluaran ini membantu Anda dengan cepat mengidentifikasi bagian kode mana yang paling banyak mengonsumsi memori, sehingga Anda dapat menargetkan area tersebut untuk dioptimalkan.
Objgraph adalah pustaka Python yang dirancang untuk membantu pengembang memvisualisasikan dan menganalisis referensi objek dalam kode. Pustaka ini menyediakan alat untuk membuat grafik visual yang menunjukkan bagaimana objek di memori saling mereferensikan. Visualisasi ini bermanfaat untuk memahami struktur dan relasi dalam program Anda, mengidentifikasi kebocoran memori, dan mengoptimalkan penggunaan memori.
Pertama, mari pasang pustaka objgraph. Anda dapat memasangnya menggunakan pip:
pip install objgraph
objgraphobjgraph menawarkan beberapa fitur penting untuk profiling dan visualisasi memori:
objgraph, Anda dapat membuat representasi visual objek dan referensinya. Ini membantu Anda memahami bagaimana objek saling terhubung, sehingga debugging dan optimasi kode menjadi lebih mudah.Mari telusuri beberapa contoh untuk melihat bagaimana objgraph digunakan dalam praktik.
Contoh 1: Menghasilkan grafik referensi objek
Misalkan kita memiliki kelas sederhana dan membuat beberapa instance:
class Node:
def __init__(self, value):
self.value = value
self.children = []
# Create some nodes
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
# Establish relationships
node1.children.append(node2)
node2.children.append(node3)
import Objgraph
# Generate a graph of object references
objgraph.show_refs([node1], filename='object_refs.png')
Pada contoh ini, kita mendefinisikan kelas Node dan membuat instance node beserta relasinya. Fungsi objgraph.show_refs() menghasilkan grafik visual referensi objek mulai dari node1 dan menyimpannya sebagai object_refs.png. Grafik ini membantu kita memahami bagaimana node saling terhubung.
Contoh 2: Mendeteksi referensi melingkar
Untuk mendeteksi referensi melingkar, kita dapat menggunakan fungsi objgraph.find_backref_chain():
# Create a circular reference
node 3.children.append(node1)
# Detect circular references
chain = objgraph.find_backref_chain(node1, objgraph.is_proper_module)
objgraph.show_chain(chain, filename='circular_refs.png')
Di sini, kita membuat referensi melingkar dengan menambahkan node1 ke children node3. Fungsi objgraph.find_backref_chain() mendeteksi referensi melingkar ini, dan objgraph.show_chain memvisualisasikannya, menyimpan keluaran sebagai circular_refs.png.
Contoh 3: Menganalisis tipe dan ukuran objek
Untuk menganalisis tipe dan ukuran objek, kita dapat menggunakan objgraph.show_most_common_types dan objgraph.by_type:
# Show the most common object types
objgraph.show_most_common_types()
# Get the details of a specific object type
objs = objgraph.by_type('Node')
objgraph.show_refs(objs[:3], refcounts=True, filename='node_details.png')
Dalam contoh ini, objgraph.show_most_common_types menampilkan tipe objek yang paling umum saat ini di memori. Fungsi objgraph.by_type() mengambil semua instance kelas Node, dan kita memvisualisasikan referensinya, termasuk jumlah referensi, dengan menghasilkan grafik lain yang disimpan sebagai node_details.png.
Sekarang mari kita lihat berbagai teknik untuk menggunakan alat profiling memori secara efektif. Kita akan berfokus pada profiling fungsi tertentu, melacak penggunaan memori secara keseluruhan, dan memvisualisasikan grafik objek.
Targetkan fungsi spesifik dengan memory_profiler atau tracemalloc.
memory_profilermemory_profiler menawarkan cara langsung untuk memantau konsumsi memori baris demi baris di dalam fungsi Anda, membantu Anda menemukan area yang penggunaan memorinya dapat dikurangi.
from memory_profiler import profile
@profile
def allocate_memory():
a = [i for i in range(10000)]
b = [i ** 2 for i in range(10000)]
return a, b
if __name__ == "__main__":
allocate_memory()
tracemallocimport tracemalloc
tracemalloc.start()
def allocate_memory():
a = [i for i in range(10000)]
b = [i ** 2 for i in range(10000)]
return a, b
allocate_memory()
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
Untuk memantau total penggunaan memori program dari waktu ke waktu, kita dapat menggunakan modul bawaan tracemalloc. Berikut cara kita melacak penggunaan memori keseluruhan dan menafsirkan hasilnya untuk mengidentifikasi tren.
Langkah menggunakan tracemalloc
Kita memulai dengan menginisialisasi pelacakan memori di awal skrip.
import tracemalloc
tracemalloc.start()
Kemudian kita mengeksekusi bagian kode yang ingin kita pantau.
def run_heavy_computation():
a = [i for i in range(10000)]
b = [i**2 for i in range(10000)]
return a, b
run_heavy_computation()
Kita mengambil snapshot penggunaan memori. Ini memungkinkan kita menangkap status alokasi memori pada titik yang berbeda.
snapshot1 = tracemalloc.take_snapshot()
run_heavy_computation()
snapshot2 = tracemalloc.take_snapshot()
Terakhir, kita membandingkan snapshot untuk memahami pola penggunaan memori dan mendeteksi kebocoran.
stats = snapshot2.compare_to(snapshot1, 'lineno')
for stat in stats[:10]:
print(stat)
Contoh
import tracemalloc
# Start tracing memory allocations
tracemalloc.start()
# Function to run heavy computation
def run_heavy_computation():
a = [i for i in range(10000)]
b = [i**2 for i in range(10000)]
return a, b
# Initial memory usage snapshot
snapshot1 = tracemalloc.take_snapshot()
# Perform memory allocations
run_heavy_computation()
# Memory usage snapshot after allocations
snapshot2 = tracemalloc.take_snapshot()
# Compare the snapshots
stats = snapshot2.compare_to(snapshot1, 'lineno')
# Print the top memory-consuming lines of code
print("[ Top 10 memory consumers ]")
for stat in stats[:10]:
print(stat)
# Stop tracing memory allocations
tracemalloc.stop()
Berikut beberapa tips untuk membantu Anda memahami data profiling:
Dengan pustaka objgraph, kita dapat membuat visualisasi relasi antar objek. Ini membantu kita menganalisis penggunaan memori, mendeteksi kebocoran, dan memahami umur objek.
Berikut proses langkah demi langkah untuk memvisualisasikan grafik objek. Pertama, kita akan menghasilkan grafik referensi objek; kemudian, kita akan mendeteksi referensi melingkar; terakhir, kita akan menganalisis grafiknya.
import objgraph
class Node:
def __init__(self, value):
self.value = value
self.children = []
# Create some nodes and establish relationships
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.children.append(node2)
node2.children.append(node3)
# Generate a graph of object references
objgraph.show_refs([node1], filename='object_refs.png')
# Create a circular reference
node3.children.append(node1)
# Detect circular references
chain = objgraph.find_backref_chain(node1, objgraph.is_proper_module)
objgraph.show_chain(chain, filename='circular_refs.png')
# Show the most common object types
objgraph.show_most_common_types()
# Get details of a specific object type
nodes = objgraph.by_type('Node')
objgraph.show_refs(nodes[:3], refcounts=True, filename='node_details.png')
Contoh
import objgraph
class Node:
def __init__(self, value):
self.value = value
self.children = []
# Create some nodes and establish relationships
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.children.append(node2)
node2.children.append(node3)
# Generate a graph of object references
objgraph.show_refs([node1], filename='object_refs.png')
# Create a circular reference
node3.children.append(node1)
# Detect circular references
chain = objgraph.find_backref_chain(node1, objgraph.is_proper_module)
objgraph.show_chain(chain, filename='circular_refs.png')
# Show the most common object types
objgraph.show_most_common_types()
# Get details of a specific object type
nodes = objgraph.by_type('Node')
objgraph.show_refs(nodes[:3], refcounts=True, filename='node_details.png')
Sebagai langkah akhir, kita menganalisis grafik. Kita mempertimbangkan langkah-langkah berikut secara berurutan:
Berikut beberapa tips kunci dan praktik terbaik agar Anda mendapatkan hasil maksimal dari upaya profiling:
Dalam tutorial ini, kita membahas alat dan teknik penting untuk memahami dan mengoptimalkan penggunaan memori di aplikasi Python Anda. Teknik ini mencakup memory_profiler yang menawarkan cara langsung untuk memantau konsumsi memori baris demi baris di dalam fungsi, serta objgraph yang menyediakan kemampuan visualisasi kuat, memungkinkan Anda menganalisis relasi objek, mendeteksi referensi melingkar, dan memahami struktur penggunaan memori Anda.
Dengan mengintegrasikan alat profiling memori ke dalam alur kerja pengembangan, Anda dapat memperoleh wawasan berharga tentang bagaimana kode mengelola memori, membantu Anda membuat keputusan optimasi yang tepat, dan meningkatkan performa serta keandalan aplikasi secara keseluruhan. Baik Anda mengerjakan skrip kecil maupun sistem berskala besar, profiling memori adalah praktik penting bagi setiap pengembang Python yang ingin menulis kode yang efisien dan tangguh.
Untuk memperdalam pemahaman dan keterampilan Anda dalam profiling memori dan menulis kode efisien, pertimbangkan untuk mengambil Kursus Menulis Kode Efisien di Python. Selain itu, kursus Pemrograman Python kami menawarkan ikhtisar komprehensif tentang praktik terbaik dan teknik lanjutan untuk membantu Anda menjadi pengembang yang andal.
Penulis teknis yang mengkhususkan diri pada AI, ML, dan ilmu data, membuat gagasan kompleks menjadi jelas dan mudah diakses.
Belajar Python dengan DataCamp
Kursus
Kursus
Kursus
blogs
David Woods
13 mnt
blogs
Hugo Bowne-Anderson
13 mnt
blogs
Dario Radečić
15 mnt

blogs
Javier Canales Luna
14 mnt