Kami mencari kebocoran memori dalam aplikasi Python

ยกHola! kami melanjutkan serangkaian publikasi yang didedikasikan untuk peluncuran kursus "Pengembang web dengan Python" dan saat ini kami sedang membagikan terjemahan artikel menarik lainnya kepada Anda.

Di Zendesk, kami menggunakan Python untuk membuat produk pembelajaran mesin. Dalam aplikasi pembelajaran mesin, salah satu masalah paling umum yang kami temui adalah kebocoran memori dan lonjakan memori. Kode python biasanya dieksekusi dalam wadah menggunakan kerangka kerja pemrosesan terdistribusi seperti Hadoop , Spark, dan AWS Batch . Setiap wadah dialokasikan jumlah memori yang tetap. Segera setelah eksekusi kode melebihi batas memori yang ditentukan, wadah akan berhenti bekerja karena kesalahan yang terjadi karena kekurangan memori.



Anda dapat dengan cepat memperbaiki masalah dengan mengalokasikan lebih banyak memori. Namun, ini dapat menyebabkan pemborosan sumber daya dan mempengaruhi stabilitas aplikasi karena ledakan memori yang tidak terduga. Penyebab kebocoran memori dapat sebagai berikut :

  • Penyimpanan panjang benda besar yang tidak dihapus;
  • Tautan loopback dalam kode;
  • Pustaka C / ekstensi C yang menyebabkan kebocoran memori;

Ini adalah praktik yang baik untuk profil penggunaan memori dengan aplikasi untuk mendapatkan pemahaman yang lebih baik tentang efisiensi ruang kode dan paket yang digunakan.

Artikel ini membahas aspek-aspek berikut:

  • Membuat profil penggunaan memori aplikasi seiring waktu;
  • Cara memeriksa penggunaan memori di bagian tertentu dari program;
  • Tip untuk kesalahan debugging yang disebabkan oleh masalah memori.

Memori profil dari waktu ke waktu

Anda bisa melihat penggunaan memori variabel selama eksekusi program Python menggunakan paket memory-profiler .

# install the required packages pip install memory_profiler pip install matplotlib # run the profiler to record the memory usage # sample 0.1s by defaut mprof run --include-children python fantastic_model_building_code.py # plot the recorded memory usage mprof plot --output memory-profile.png 



Gambar A. Memory profiling sebagai fungsi waktu

Opsi include-children akan memungkinkan penggunaan memori oleh setiap proses anak yang dihasilkan oleh proses induk. Gambar A mencerminkan proses pembelajaran berulang, yang menyebabkan memori meningkat dalam siklus pada saat-saat ketika paket data pelatihan diproses. Objek dihapus selama pengumpulan sampah.

Jika penggunaan memori terus meningkat, ini dianggap sebagai potensi ancaman kebocoran memori. Berikut ini contoh kode yang mencerminkan ini:


Gambar B. Penggunaan memori meningkat dari waktu ke waktu

Anda harus menetapkan breakpoints di debugger segera setelah penggunaan memori melebihi batas tertentu. Untuk melakukan ini, Anda dapat menggunakan parameter pdb-mmem , yang nyaman saat pemecahan masalah.

Memory dump pada titik waktu tertentu

Berguna untuk memperkirakan jumlah objek besar yang diperkirakan sebelumnya dalam program dan apakah mereka harus diduplikasi dan / atau dikonversi ke berbagai format.

Untuk analisis lebih lanjut dari objek dalam memori, Anda dapat membuat tumpukan di baris tertentu dari program menggunakan muppy .

 # install muppy pip install pympler # Add to leaky code within python_script_being_profiled.py from pympler import muppy, summary all_objects = muppy.get_objects() sum1 = summary.summarize(all_objects) # Prints out a summary of the large objects summary.print_(sum1) # Get references to certain types of objects such as dataframe dataframes = [ao for ao in all_objects if isinstance(ao, pd.DataFrame)] for d in dataframes: print d.columns.values print len(d) 


Gambar C. Contoh dump heap dump

Pustaka profil memori lain yang bermanfaat adalah objgraph , yang memungkinkan Anda untuk menghasilkan grafik untuk memeriksa asal-usul objek.

Pointer yang berguna

Pendekatan yang berguna adalah membuat "test case" kecil yang menjalankan kode yang sesuai yang menyebabkan kebocoran memori. Pertimbangkan untuk menggunakan subkumpulan data yang dipilih secara acak jika input yang lengkap membutuhkan waktu lama untuk diproses.

Lakukan tugas dengan beban memori tinggi dalam proses terpisah

Python tidak langsung membebaskan memori untuk sistem operasi. Untuk memastikan bahwa memori telah dibebaskan, Anda harus memulai proses terpisah setelah mengeksekusi sepotong kode. Anda dapat mempelajari lebih lanjut tentang pemulung di Python di sini .

Debugger dapat menambahkan referensi ke objek.

Jika Anda menggunakan breakpoint debugger seperti pdb , semua objek yang dibuat yang direferensikan secara manual oleh debugger akan tetap ada dalam memori. Ini dapat membuat kebocoran memori karena kesalahan, karena objek tidak dihapus secara tepat waktu.

Waspadalah terhadap paket yang dapat menyebabkan kebocoran memori.

Beberapa perpustakaan di Python berpotensi menyebabkan kebocoran, misalnya pandas memiliki beberapa masalah kebocoran memori yang diketahui.
Selamat berburu kebocoran!

Tautan yang bermanfaat:

docs.python.org/3/c-api/memory.html
docs.python.org/3/library/debug.html

Tulis di komentar jika artikel ini bermanfaat bagi Anda. Dan mereka yang ingin belajar lebih banyak tentang kursus kami, kami mengundang Anda untuk membuka hari , yang akan diadakan pada 22 April.

Source: https://habr.com/ru/post/id448474/


All Articles