最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決Python中由于logging模塊誤用導(dǎo)致的內(nèi)存泄露

 更新時(shí)間:2015年04月23日 17:01:47   作者:C Wong  
這篇文章主要介紹了解決Python中由于logging模塊誤用導(dǎo)致的內(nèi)存泄露,針對由于過多的UDP連接所產(chǎn)生的問題,需要的朋友可以參考下

首先介紹下怎么發(fā)現(xiàn)的吧, 線上的項(xiàng)目日志是通過 logging 模塊打到 syslog 里, 跑了一段時(shí)間后發(fā)現(xiàn) syslog 的 UDP 連接超過了 8W, 沒錯(cuò)是 8 W. 主要是 logging 模塊用的不對

我們之前有這么一個(gè)需求, 就是針對每一個(gè)連接日志輸出當(dāng)前連接的信息, 所以每一個(gè) 連接就創(chuàng)建了一個(gè)日志實(shí)例, 并分配一個(gè) Formatter, 創(chuàng)建日志實(shí)例為了區(qū)分其他連接 所以我就簡單粗暴的用了當(dāng)前對象的 id 來作為日志名稱:

import logging


class Connection(object):
  def __init__(self):
    self._logger_name = "Connection.{}".format(id(self))
    self.logger = logging.getLogger(self._logger_name)

當(dāng)然測試環(huán)境是開 DEBUG, 開 DEBUG 就不會(huì)往 syslog 里打, 所以不會(huì)出現(xiàn) UDP 連接數(shù) 過多, 也就不會(huì)知道有內(nèi)存泄露的, 我們來看看這樣為什么會(huì)導(dǎo)致內(nèi)存泄露, 首先看看 getLogger 的代碼:

def getLogger(name=None):
  """
  Return a logger with the specified name, creating it if necessary.

  If no name is specified, return the root logger.
  """
  if name:
    return Logger.manager.getLogger(name)
  else:
    return root

主要調(diào)用了 Logger.manager.getLogger, 這個(gè)函數(shù)有下面一段代碼片段

      if name in self.loggerDict:
        rv = self.loggerDict[name]
        if isinstance(rv, PlaceHolder):
          ph = rv
          rv = (self.loggerClass or _loggerClass)(name)
          rv.manager = self
          self.loggerDict[name] = rv
          self._fixupChildren(ph, rv)
          self._fixupParents(rv)
      else:
        rv = (self.loggerClass or _loggerClass)(name)
        rv.manager = self
        self.loggerDict[name] = rv
        self._fixupParents(rv)

logging 模塊為了保證同一個(gè)名稱引用同一個(gè)日志實(shí)例,所以就把所有的日志實(shí)例全部存 在了一個(gè) loggerDict 的字典里, 所以除非程序退出, 創(chuàng)建的日志實(shí)例引用是不會(huì)釋放的, 所以日志實(shí)例里的 handlers 也不會(huì)釋放. 之前我又用的對象的 id 來作為日志名稱 的一部分, 所以 SyslogHandler 創(chuàng)建的 UDP 連接就一直被占用導(dǎo)致了過多的 UDP 連接.

為了解決這個(gè)問題我在連接關(guān)閉的時(shí)候加入了如下代碼:

logging.Logger.manager.loggerDict.pop(self._logger_name)
self.logger.manager = None
self.logger.handlers = []

按說只加上上面第一行的代碼就應(yīng)該釋放了, 但是沒有, 所以又有了第三行代碼, SyslogHandler 才最終釋放, 這個(gè)問題暫時(shí)還不知道為什么, 還需要再查查.

2015-03-30 更新 如果日志名稱是以 . 分隔, logging 模塊則會(huì)將最后一部分作為日志名, 并往上去尋找 父 Logger, 如果找不到則創(chuàng)建 PlaceHolder 對象作為父, 并引用 Logger.

比如創(chuàng)建的 Logger 名稱為 a.b.c, 那么實(shí)際的名稱則為 c, 并將 b 作為 c 的父, a 作為 b 的 父, 如果沒有該名稱的 Logger 則創(chuàng)建 PlaceHolder 對象作為代替, PlaceHolder 會(huì)創(chuàng)建對當(dāng)前 Logger 的引用. 所以需要被回收的日志對象名稱里不應(yīng)包含 .

相關(guān)文章

  • 使用Python壓縮和解壓縮zip文件的教程

    使用Python壓縮和解壓縮zip文件的教程

    這篇文章主要介紹了使用Python壓縮和解壓縮zip文件的教程,主要用到了zipfile包,需要的朋友可以參考下
    2015-05-05
  • Python FastAPI 多參數(shù)傳遞的示例詳解

    Python FastAPI 多參數(shù)傳遞的示例詳解

    這篇文章主要介紹了Python FastAPI 多參數(shù)傳遞,FastAPI通過模板來匹配URL中的參數(shù)列表,大概分為三類方式傳遞參數(shù),每種方式結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 使用python播放音頻的示例代碼

    使用python播放音頻的示例代碼

    在Python中,我們可以使用多種庫來播放音頻文件,其中最常用的是pygame庫和playsound庫,本文給大家分享使用這些庫的示例,對python播放音頻示例代碼感興趣的朋友一起看看吧
    2024-02-02
  • Python pip通過requirements.txt 文件安裝依賴

    Python pip通過requirements.txt 文件安裝依賴

    requirements.txt是定義項(xiàng)目依賴的python包,可通過工具生成,本文主要介紹了Python pip通過requirements.txt文件安裝依賴,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Python標(biāo)準(zhǔn)庫datetime?date模塊的詳細(xì)介紹

    Python標(biāo)準(zhǔn)庫datetime?date模塊的詳細(xì)介紹

    這篇文章主要介紹了Python標(biāo)準(zhǔn)庫datetime?date模塊的詳細(xì)介紹,datetime是Python提供的操作日期和時(shí)間的標(biāo)準(zhǔn)庫,主要有datetime.date模塊、datetime.time模塊及datetime.datetime模塊
    2022-07-07
  • python argparse模塊通過后臺(tái)傳遞參數(shù)實(shí)例

    python argparse模塊通過后臺(tái)傳遞參數(shù)實(shí)例

    這篇文章主要介紹了python argparse模塊通過后臺(tái)傳遞參數(shù)實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • jmeter執(zhí)行python腳本的實(shí)現(xiàn)示例

    jmeter執(zhí)行python腳本的實(shí)現(xiàn)示例

    本文主要介紹了jmeter執(zhí)行python腳本的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Python 刪除文件每一行的行號(hào)思路解讀

    Python 刪除文件每一行的行號(hào)思路解讀

    有時(shí)候我們需要?jiǎng)h除代碼中的行號(hào),比如在把代碼復(fù)制到記事本中的時(shí)候,前邊的行號(hào)不刪除就沒辦法運(yùn)行,我們要手動(dòng)刪掉代碼段前的行號(hào),才能運(yùn)行代碼。如果有幾百行,就非常累,非常不爽,所以這種事還是要交給計(jì)算機(jī)去做
    2021-11-11
  • Python 實(shí)現(xiàn)網(wǎng)課實(shí)時(shí)監(jiān)控自動(dòng)簽到、打卡功能

    Python 實(shí)現(xiàn)網(wǎng)課實(shí)時(shí)監(jiān)控自動(dòng)簽到、打卡功能

    這篇文章主要介紹了Python實(shí)現(xiàn)網(wǎng)課實(shí)時(shí)監(jiān)控自動(dòng)簽到,打卡功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • python 實(shí)現(xiàn)兩個(gè)變量值進(jìn)行交換的n種操作

    python 實(shí)現(xiàn)兩個(gè)變量值進(jìn)行交換的n種操作

    這篇文章主要介紹了python 實(shí)現(xiàn)兩個(gè)變量值進(jìn)行交換的n種操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

拜城县| 兴仁县| 武强县| 壶关县| 图们市| 合肥市| 扎赉特旗| 泰州市| 于田县| 宁安市| 德令哈市| 宜宾县| 白城市| 南岸区| 铁岭市| 霍邱县| 林芝县| 壶关县| 阿拉尔市| 正镶白旗| 昌图县| 崇文区| 乌拉特前旗| 富阳市| 新乡县| 溆浦县| 南昌县| 雷山县| 尉氏县| 农安县| 凤阳县| 黄山市| 临潭县| 静宁县| 洪雅县| 安吉县| 温泉县| 惠东县| 黔东| 册亨县| 东乌|