python內存的查看和解決

在工作中出現了一個未曾注意的問題:python的內存泄露問題,直接說問題和解決方式:

我遇到的問題出現內存泄露主要是因爲:使用c類型申請的變量數組造成的泄露,因爲申請(ctype.c_int*len)() 這類的數組的時候,沒有手動清除,導致在程序結束的時候,沒有自動回收,導致內存不斷的增加。

  1. python內存管理機制:
    1. 根據變量的引用計數,引用計數變爲0,在結束的時候,垃圾回收機制,會回收;
    2. 標記清除:如果兩個對象的引用計數都是1,兩個對象是循環引用的,雖然引用計數表現爲非0,但是實際上有效的引用計數爲0,這兩個變量都需要清除;
    3. 分代回收:垃圾回收分爲0,1,2代;這個就是有的變量存活時間比較長,這種變量往往不能及時回收;這種就需要手動清楚;
  2. 調優的手段:
    1. 避免循環引用
    2. 手動垃圾回收
    3. 調高垃圾回收閾值(沒有試驗,前兩個都用了。自認爲系統的設置一般不動,畢竟不是專業的運維的。)
  3. 內存的問題使用的方式:
    1. heap():在python3中引入guppy3,from guppy import hpy   然後打印出棧中內存的使用情況:print(hpy().heap())
    2. import objgraph,顯示內存中變量的增長情況使用objgraph.show_growth()
    3. memory_profiler:在函數的前邊添加@profile 顯示內存的變化,我這裏沒有用這個。
    4. 使用tracemalloc,查看沒有釋放內存的變量和位置,這是我主要使用的方式,
      1. 使用tracker,先查看是否有內存泄露,
        1. from pympler import tracker,summary,muppy
        2. memory_tracer = tracker.SummaryTracker()
        3. 程序流程
        4. 查看是否有內存泄露:memory_tracer.print_diff() 
      2. 使用tracemalloc 查看泄露的位置
        1. import tracemalloc  
        2. tracemalloc.start()    運行的程序     
        3. snapshot1 = tracemalloc.take_snapshot()
        4. top_stats = snapshot1.statistics('lineno')   #定位變量的名字和位置
        5. for stat in top_stats[:limit]:   #limit:自己定義個數,要顯示的個數
          1. print(stat)
        6. 根據這個可以找到沒有釋放掉位置,找到變量,在使用完變量後,要手動銷燬,del +變量的名字
        7. 在結束後使用gc.collect(),釋放掉需要釋放的變量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章