Python argparse出现在gc.garbage中

时间:2016-07-20 09:50:27

标签: python memory-leaks garbage-collection

我试图在python应用程序中调试内存泄漏,我可以看到很多非收集的对象属于模块argparse

这里是一个重现错误的最小脚本

import gc
gc.set_debug(gc.DEBUG_LEAK)

def get_cli_arguments():
    import argparse
    parser = argparse.ArgumentParser(description='Launch a RHM server')
    parser.add_argument(
        '--port',
        metavar='port',
        type=int,
        nargs='?',
        help='the server port',
        default=8003
    )
    return vars(parser.parse_args())


def main():
    args = get_cli_arguments()
    x = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"


main()
gc.collect()
print(gc.garbage)

我得到了以下输出

gc: collectable <dict 0x7f9a8b303c58>
gc: collectable <dict 0x7f9a8b303d70>
gc: collectable <list 0x7f9a8b350ea8>
gc: collectable <list 0x7f9a8b350b00>
gc: collectable <list 0x7f9a8b3dca70>
gc: collectable <_ArgumentGroup 0x7f9a8b3e6250>
gc: collectable <dict 0x7f9a8b301910>
gc: collectable <list 0x7f9a8b3535a8>
gc: collectable <list 0x7f9a8b3e1758>
gc: collectable <function 0x7f9a8b3d2d70>
gc: collectable <dict 0x7f9a8b301a28>
gc: collectable <list 0x7f9a8b3e17e8>
gc: collectable <_HelpAction 0x7f9a8b3e60d0>
gc: collectable <dict 0x7f9a8b3014b0>
gc: collectable <HelpFormatter 0x7f9a8b2f7f90>
gc: collectable <_Section 0x7f9a8b2f7fd0>
gc: collectable <dict 0x7f9a8b3016e0>
gc: collectable <list 0x7f9a8b350248>
gc: collectable <dict 0x7f9a8b3015c8>
gc: collectable <dict 0x7f9a8b303e88>
gc: collectable <list 0x7f9a8b3e1d40>
gc: collectable <_StoreAction 0x7f9a8b30a090>
gc: collectable <dict 0x7f9a8b2f9c58>
gc: collectable <HelpFormatter 0x7f9a8b30a0d0>
gc: collectable <_Section 0x7f9a8b30a110>
gc: collectable <dict 0x7f9a8b3017f8>
gc: collectable <list 0x7f9a8b36c200>
gc: collectable <dict 0x7f9a8b301b40>
[{'action': {'store_false': <class 'argparse._StoreFalseAction'>, 'append_const': <class 'argparse._AppendConstAction'>, 'help': <class 'argparse._HelpAction'>, None: <class 'argparse._StoreAction'>, 'store_true': <class 'argparse._StoreTrueAction'>, 'count': <class 'argparse._CountAction'>, 'store_const': <class 'argparse._StoreConstAction'>, 'version': <class 'argparse._VersionAction'>, 'store': <class 'argparse._StoreAction'>, 'parsers': <class 'argparse._SubParsersAction'>, 'append': <class 'argparse._AppendAction'>}, 'type': {None: <function identity at 0x7f9a8b3d2d70>}}, {'store_false': <class 'argparse._StoreFalseAction'>, 'append_const': <class 'argparse._AppendConstAction'>, 'help': <class 'argparse._HelpAction'>, None: <class 'argparse._StoreAction'>, 'store_true': <class 'argparse._StoreTrueAction'>, 'count': <class 'argparse._CountAction'>, 'store_const': <class 'argparse._StoreConstAction'>, 'version': <class 'argparse._VersionAction'>, 'store': <class 'argparse._StoreAction'>, 'parsers': <class 'argparse._SubParsersAction'>, 'append': <class 'argparse._AppendAction'>}, [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port')], [], [], <argparse._ArgumentGroup object at 0x7f9a8b3e6250>, {'_mutually_exclusive_groups': [], '_negative_number_matcher': <_sre.SRE_Pattern object at 0x7f9a8b437290>, 'description': None, '_option_string_actions': {'--port': _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port'), '-h': _HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), '--help': _HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)}, 'title': 'optional arguments', '_has_negative_number_optionals': [], '_defaults': {}, 'prefix_chars': '-', 'argument_default': None, '_registries': {'action': {'store_false': <class 'argparse._StoreFalseAction'>, 'append_const': <class 'argparse._AppendConstAction'>, 'help': <class 'argparse._HelpAction'>, None: <class 'argparse._StoreAction'>, 'store_true': <class 'argparse._StoreTrueAction'>, 'count': <class 'argparse._CountAction'>, 'store_const': <class 'argparse._StoreConstAction'>, 'version': <class 'argparse._VersionAction'>, 'store': <class 'argparse._StoreAction'>, 'parsers': <class 'argparse._SubParsersAction'>, 'append': <class 'argparse._AppendAction'>}, 'type': {None: <function identity at 0x7f9a8b3d2d70>}}, '_group_actions': [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port')], '_action_groups': [], 'conflict_handler': 'error', '_actions': [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port')]}, [], [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port')], <function identity at 0x7f9a8b3d2d70>, {None: <function identity at 0x7f9a8b3d2d70>}, ['-h', '--help'], _HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), {'const': None, 'help': 'show this help message and exit', 'option_strings': ['-h', '--help'], 'dest': 'help', 'required': False, 'nargs': 0, 'choices': None, 'default': '==SUPPRESS==', 'container': <argparse._ArgumentGroup object at 0x7f9a8b3e6250>, 'type': None, 'metavar': None}, <argparse.HelpFormatter object at 0x7f9a8b2f7f90>, <argparse._Section object at 0x7f9a8b2f7fd0>, {'items': [], 'formatter': <argparse.HelpFormatter object at 0x7f9a8b2f7f90>, 'heading': None, 'parent': None}, [], {'_current_indent': 0, '_level': 0, '_indent_increment': 2, '_action_max_length': 0, '_max_help_position': 24, '_width': 78, '_root_section': <argparse._Section object at 0x7f9a8b2f7fd0>, '_long_break_matcher': <_sre.SRE_Pattern object at 0x7f9a8b33e258>, '_prog': 'prout.py', '_current_section': <argparse._Section object at 0x7f9a8b2f7fd0>, '_whitespace_matcher': <_sre.SRE_Pattern object at 0x7f9a8b347750>}, {'--port': _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port'), '-h': _HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), '--help': _HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)}, ['--port'], _StoreAction(option_strings=['--port'], dest='port', nargs='?', const=None, default=8003, type=<type 'int'>, choices=None, help='the server port', metavar='port'), {'const': None, 'help': 'the server port', 'option_strings': ['--port'], 'dest': 'port', 'required': False, 'nargs': '?', 'choices': None, 'default': 8003, 'container': <argparse._ArgumentGroup object at 0x7f9a8b3e6250>, 'type': <type 'int'>, 'metavar': 'port'}, <argparse.HelpFormatter object at 0x7f9a8b30a0d0>, <argparse._Section object at 0x7f9a8b30a110>, {'items': [], 'formatter': <argparse.HelpFormatter object at 0x7f9a8b30a0d0>, 'heading': None, 'parent': None}, [], {'_current_indent': 0, '_level': 0, '_indent_increment': 2, '_action_max_length': 0, '_max_help_position': 24, '_width': 78, '_root_section': <argparse._Section object at 0x7f9a8b30a110>, '_long_break_matcher': <_sre.SRE_Pattern object at 0x7f9a8b33e258>, '_prog': 'prout.py', '_current_section': <argparse._Section object at 0x7f9a8b30a110>, '_whitespace_matcher': <_sre.SRE_Pattern object at 0x7f9a8b347750>}]

我无法在argparse中找到任何关于此类问题的报告,我做错了什么?

1 个答案:

答案 0 :(得分:2)

这一行

gc.set_debug(gc.DEBUG_LEAK)

equivalent to saying

gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_SAVEALL)

by setting DEBUG_SAVEALL

  

设置后,找到的所有无法访问的对象都将被附加到垃圾而不是被释放。

事实上,如果你没有设置DEBUG_LEAK,这些被释放。 (在不设置DEBUG_LEAK

的情况下试用您的代码

您可能想要的标志是gc.DEBUG_UNREACHABLE,它显示有关无法访问(并且可能应该被释放)但无法被垃圾回收器释放的对象的信息。

您还可以查看DEBUG_COLLECTABLE以帮助识别可以被释放的循环引用。