<div style="line-height:1.7;color:#000000;font-size:14px;font-family:Arial"><div>Hello,</div><div>    I use backdoor of eventlet to enable gc.DEBUG_LEAK, and after wait a few minutes, i can sure that there will some objects that can not be collected by gc.collect in gc.garbage. </div><div>Those looks like this (catched in ceilometer-collector)</div><div><br></div><div><div>['_context_auth_token', 'auth_token', 'new_pass'],</div><div> (<cell at 0x363bc58: list object at 0x361c170>,</div><div>  <cell at 0x363bda8: function object at 0x361a5f0>),</div><div> <function _fix_passwords at 0x361a5f0>,</div><div> <cell at 0x363bde0: list object at 0x363c680>,</div><div> <cell at 0x363bd70: function object at 0x361a668>,</div><div> ['_context_auth_token', 'auth_token', 'new_pass'],</div><div> (<cell at 0x363bde0: list object at 0x363c680>,</div><div>  <cell at 0x363bd70: function object at 0x361a668>),</div><div> <function _fix_passwords at 0x361a668>,</div><div> <cell at 0x363bf30: list object at 0x361b680>,</div><div> <cell at 0x363e168: function object at 0x361a758>,</div><div> ['_context_auth_token', 'auth_token', 'new_pass'],</div><div> (<cell at 0x363bf30: list object at 0x361b680>,</div><div>  <cell at 0x363e168: function object at 0x361a758>),</div><div> <function _fix_passwords at 0x361a758>,</div><div> <cell at 0x363e1a0: list object at 0x363cdd0>,</div><div> <cell at 0x363e130: function object at 0x361a7d0>,</div></div><br><div><span style="line-height: 1.7;">and i suspect those code in oslo.messaging</span></div><div><span style="line-height: 1.7;"><br></span></div><div><div>def _safe_log(log_func, msg, msg_data):</div><div>    """Sanitizes the msg_data field before logging."""</div><div>    SANITIZE = ['_context_auth_token', 'auth_token', 'new_pass']</div><div><br></div><div>    def _fix_passwords(d):</div><div>        """Sanitizes the password fields in the dictionary."""</div><div>        for k in d.iterkeys():</div><div>            if k.lower().find('password') != -1:</div><div>                d[k] = '<SANITIZED>'</div><div>            elif k.lower() in SANITIZE:</div><div>                d[k] = '<SANITIZED>'</div><div>            elif isinstance(d[k], dict):</div><div>                _fix_passwords(d[k])</div><div>        return d</div><div><br></div><div>    return log_func(msg, _fix_passwords(copy.deepcopy(msg_data)))</div></div><div><br></div><div>i can resolve this problem by add _fix_passwords = None before _safe_log returns.</div><div><br></div><div>But i do not really understand why this problem happened, and in depth why the gc can not collect those object. Although i can make those uncollectable objects disappeared.</div><div>But this is not good enough, because if you do not understand it you will write out some code like this in future, and then also has memory leak too.</div><div><br></div><div>So can some one helps me give some detailed on recursive closure used like the code above, and on why gc can not collect them.</div><div>Thanks a lot lot ......</div><div><br></div><div>--<br><div>Best</div><div>    Li Tianqing</div></div></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>