我有一个生成线程响应处理程序的服务器子类,这些处理程序依次启动应用程序线程。一切都很顺利,除非当我使用ObjGraph时,我看到正确数量的应用程序线程正在运行(我正在进行负载测试并对其进行限制以保持 35 个应用程序实例运行)。
调用objgraph.typestats()可以细分解释器中当前存在的每个对象的实例数量(根据 GC)。查看内存泄漏的输出,我发现 700 个记录器实例——这将是服务器产生的响应处理程序的总数。
当应用程序线程退出 run() 方法时,我调用了 logger.removehandler(memoryhandler) 和 logger.removehandler(filehandler) 以确保没有对记录器实例的延迟引用,而且记录器实例在应用程序线程中完全隔离(没有外部引用它)。作为消除这些记录器实例的最后一步,run() 中的最后一条语句是 del self.logger
为了在 init() 中获取记录器,我为它提供了一个适当大的随机数来命名它,这样它对于文件访问将是不同的——我使用相同的大数字作为日志文件名的一部分以避免应用程序日志冲突。
总而言之,我有 700 个被 GC 跟踪的记录器实例,但只有 35 个活动线程 - 我该如何杀死这些记录器?一个更麻烦的工程师解决方案是创建一个记录器池,并在应用程序线程的生命周期内只获取一个记录器,但这会创建更多代码来维护,什么时候 GC 应该简单地自动处理它。