From: Kevin G. <ke...@go...> - 2004-06-08 08:01:43
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Nice work, Mike, as usual. Now to the question of alleged memory leak. Here is code and annoted output ============================================= use Log::Log4perl qw(get_logger); $Log::Log4perl::CHATTY_DESTROY_METHODS=1; Log::Log4perl->init(\ q{ log4perl.logger = DEBUG, A1 log4perl.appender.A1 = Log::Log4perl::Appender::Screen log4perl.appender.A1.layout = SimpleLayout }); $logger = get_logger(); warn "created logger $logger"; ============================================= created logger Log::Log4perl::Logger=HASH(0x8105018) at test line 13. --that's the one I created Destroying logger Log::Log4perl::Logger=HASH(0x811e474) at lib/Log/Log4perl/Logger.pm line 56. --there goes the root logger Destroying logger Log::Log4perl::Logger=HASH(0x8105018) at lib/Log/Log4perl/Logger.pm line 56. --there goes mine Destroying logger Log::Log4perl::Logger=HASH(0x811e474) at lib/Log/Log4perl/Logger.pm line 56. --there goes the root logger again Destroying appender Log::Log4perl::Appender=HASH(0x82526bc) at lib/Log/Log4perl/Appender.pm line 263. --there goes the appender --now we enter the GDP Destroying appender Log::Log4perl::Appender=HASH(0x82526bc) at lib/Log/Log4perl/Appender.pm line 263 during global destruction. --there goes the appender again Destroying logger Log::Log4perl::Logger=HASH(0x8105018) at lib/Log/Log4perl/Logger.pm line 56 during global destruction. --there goes the logger again Now I assume you're worried about those two cleanups during the GDP. Looking at the logger first, I tried dumping the structure in the DESTROY method and by the time it's in the last line of output the logger is totally empty, it's been cleaned out already. I think the reference it's cleaning up is the reference in *main:: in the script. I added "undef $logger" to the script to delete the reference from *main:: and that line disappeared from the output. So I don't think that's a problem. That leaves the Appender. Again I tried dumping the struct from DESTROY and it was totally empty. Means there's a reference to it floating around. If you look at Logger::generate_coderef(), you'll see that inside the coderef is a closure, $appenders is referenced inside the coderef but is defined outside it. That's our culprit. If you change the eval and return at the end of generate_coderef() to "return sub{}", then the "Appender during global destruction" line goes away from the output and that's it for the memory leak. So I'm pretty sure it's the closure that's the problem. With the "return sub{}" change in generate_coderef(), putting a while loop around the above code and running it forever doesn't use up any memory. Since the appender is empty by the time it gets to the GDP, I'm pretty sure that the cause of the memory leak isn't the appenders. I think it's the code eval. We're adding to the code each time through. But that's as far as I can get. Devel::Leak might help, if I built a Perl with debugging, but it's way, way past my bedtime. On the bright side, it's really not a problem unless somebody is running init() a thousand times in the life of the process, and we kind of discourage that anyway, don't we? - -- Happy Trails. . . Kevin M. Goess (and Anne and Frank) 904 Carmel Ave. Albany, CA 94706 (510)525-5217 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.3 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQFAxXI34g4/Tl71vUkRAsxmAKDGSyPd2VO8msvs0kEEmQBz+S0uqQCg1dsK bzijFBfoGHni9jf22WDk6gk= =os8v -----END PGP SIGNATURE----- |