TShopping

 找回密碼
 註冊
搜索
查看: 149|回復: 0

[教學] 在 Python 應用程序中尋找內存洩漏

[複製鏈接]
發表於 2021-8-18 22:32:04 | 顯示全部樓層 |閱讀模式
 
Push to Facebook Push to Plurk  

我們在 Zendesk 中大量使用 Python 來構建機器學習 (ML) 產品。我們在機器學習應用程序中遇到的常見性能問題之一是內存洩漏和峰值。Python 代碼通常通過分佈式處理框架(如HadoopSparkAWS Batch)在容器內執行。每個容器都分配有固定數量的內存。一旦代碼執行超過指定的內存限制,容器將因內存不足錯誤而終止。

一個快速的解決方法是增加內存分配。然而,由於不可預測的內存峰值,這可能導致資源浪費並影響產品的穩定性。內存洩漏的原因可能包括

  • 釋放洩漏記憶體的大物件
  • 代碼中的引用循環
  • 底層庫/C 擴展洩漏內存

一個有用的練習是分析應用程序的內存使用情況,以更好地了解代碼和所使用的底層包的空間效率。這篇文章涵蓋:

  • 分析時間應用程序的內存使用情況
  • 如何檢查程序特定部分的內存使用情況
  • 調試內存問題的技巧

分析時間內存

您可以使用memory-profile包查看在 Python 代碼執行期間隨時間變化的內存使用情況。

  1. # install the required packages
  2. pip install memory_profiler
  3. pip install matplotlib
  4. # run the profiler to record the memory usage
  5. # sample 0.1s by defaut
  6. mprof run --include-children python fantastic_model_building_code.py
  7. # plot the recorded memory usage
  8. mprof plot --output memory-profile.png
複製代碼

Python 應用程序 內存洩漏

Python 應用程序 內存洩漏




A. 作為時間函數的內存配置文件

選項include-children將包括通過父進程產生的任何子進程的內存使用情況。圖 A 顯示了一個迭代模型訓練過程,該過程導致內存隨著訓練數據批次的處理而循環增加。一旦垃圾收集開始,對象就會被釋放。

如果內存使用量不斷增長,則存在內存洩漏的潛在問題。這是一個虛擬示例腳本來說明這一點。


Python 應用程序 內存洩漏

Python 應用程序 內存洩漏




B. 內存佔用隨時間增加

一旦內存使用量超過特定閾值,就可以使用pdb-mmem選項設置調試器斷點 ,這對於故障排除很方便。

某個時間點的內存轉儲

了解程序中大對象的預期數量以及它們是否應該被複製和/或轉換為不同的格式非常重要。

為了進一步分析內存中的對象,可以使用muppy在程序中的某些代碼行中創建堆轉儲。

  1. # install muppy
  2. pip install pympler
  3. # Add to leaky code within python_script_being_profiled.py
  4. from pympler import muppy, summary
  5. all_objects = muppy.get_objects()
  6. sum1 = summary.summarize(all_objects)
  7. # Prints out a summary of the large objects
  8. summary.print_(sum1)
  9. # Get references to certain types of objects such as dataframe
  10. dataframes = [ao for ao in all_objects if isinstance(ao, pd.DataFrame)]
  11. for d in dataframes:
  12.   print d.columns.values
  13.   print len(d)
複製代碼

Python 應用程序 內存洩漏

Python 應用程序 內存洩漏



內存堆轉儲摘要示例

另一個有用的內存分析庫是objgraph,它可以生成對像圖來檢查對象的沿襲。


有用的指針爭取快速反饋循環

一個有用的方法是創建一個小的“測試用例”,它只運行有問題的內存洩漏代碼。如果完整的輸入數據運行時間很長,請考慮使用隨機採樣數據的子集。

在單獨的進程中運行內存密集型任務

Python 不一定會立即將內存釋放回操作系統。為了確保在一段代碼執行後釋放內存,它需要在單獨的進程中運行。此頁面提供有關Python 垃圾收集的更多詳細信息。

調試器可以添加對對象的引用

如果使用斷點調試器(例如pdb),則從調試器手動創建和引用的任何對像都將保留在內存配置文件中。這可能會產生內存洩漏的錯誤感覺,即對象未及時釋放。

注意可能會洩漏的包裹

一些 Python 庫可能存在內存洩漏。例如,pandas 有很多已知的內存洩漏問題

狩獵快樂!



原文
https://medium.com/zendesk-engin ... ations-6824d0518774

 

臉書網友討論
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2021-9-25 14:13 , Processed in 0.233597 second(s), 25 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表