2011-05-06 64 views
4

我使用Log4perl作爲包的一部分來捕獲特定的DBI連接正在做什麼。我目前的計劃是通過Log::Log4perl->get_logger($mysql_connect_id)爲每個連接創建一個新的記錄器對象,這將允許各種連接寫入不同的文件或相同的文件,而不會互相搞砸。處理Log4perl記錄器時,我不再需要它

我擔心的是當連接斷開並且不再需要記錄器時發生的情況。如果Log4perl只是讓這些記錄器無限期地存在,那聽起來就像是內存泄漏的祕訣。

在我確定它不再有用之後擺脫記錄器的最佳方式是什麼?或者相反,這甚至是一個問題 - Log4perl是否具有某種內置的處理機制,可以防止這種泄漏?


編輯:在一個問題的評論中提到,可能值得一提的是:Log :: Log4perl :: Logger有一個 DESTROY方法,看起來很有前途。然而,它沒有記錄,並引發了一堆「在字符串eq中使用未初始化值」的警告,這讓我很擔心;它感覺像一個黑客。 (但如果是做的最好的/唯一的辦法,我想問題就變成了「我如何關閉特定的警告,從一個特定的軟件包來嗎?」)

+1

['DESTROY'](http://perldoc.perl.org/perlobj.html#Destructors)方法不應該手動調用,因爲當對象將要被移除時,它將被perl本身調用從記憶裏。直接調用DESTROY不會釋放內存。 – 2011-05-06 17:09:05

+0

@伊萬:好的,廢話。非常好看的黑客太多了。謝謝你的提示。 – BlairHippo 2011-05-06 17:14:49

+1

記錄器對象是代碼引用的小散列。除非你在製作大量的東西,否則我認爲與程序在內存中存儲的任何實際數據相比,額外的內存是無關緊要的。不要擔心。 – Schwern 2011-05-09 06:38:06

回答

5

我看到的唯一方法是操縱Log::Log4perl::Logger的內部緩存。

delete $Log::Log4perl::Logger::LOGGERS_BY_NAME->{$category}; 

這是「安全的」,因爲它將會記錄:: Log4perl當前版本的工作,但它可以在更新打不破的安全。這是以前由另一個SO用戶建議的,但他們刪除了它。

我建議你make a feature request能夠刪除單個緩存項作爲API的一部分。如果你想加快它,請提交一個補丁。這非常簡單。

+0

我已經通過圍繞它設計來處理該問題,但是如果我仍然被鎖定原來的設計,這是我使用的解決方案。在我的口袋裏,這是件好事。謝謝! (順便說一句 - 我認爲我們在RL認識對方) – BlairHippo 2011-05-10 19:53:36

2

它看起來像

Log::Log4perl::Logger->cleanup(); 

調用應該刪除目前已初始化的所有內容。它應該刪除任何關聯的資源。

+0

從軌道上的Nuke網站? :-)這樣做,但如果我正確地閱讀,那麼也會擺脫我想要保留的任何記錄器。 – BlairHippo 2011-05-06 19:56:46

+0

@BlairHippo - 確實沒有正確讀取您的問題,我以爲您想徹底擺脫Log :: Log4perl。如果你想刪除一些東西,爲什麼不給它新的配置並讓自己重新初始化? – bvr 2011-05-07 08:52:54

+0

不幸的是,'cleanup()'不只是刪除自己的緩存,它積極地在每個記錄器上調用DESTROY。這是不必要的,並且會調用'cleanup()'危險。您必須知道,整個過程中的所有記錄器,即使在第三方模塊中,都不再使用。 – Schwern 2011-05-09 06:47:18

3

對不起,我想我現在終於修好了。您現在可以使用新實施的方法Log::Log4perl->remove_logger($logger)刪除未使用的記錄器(不要忘記覈對您持有的$logge的剩餘參考)。

Checked into github並應該與下一個版本(1.33)一起出去。感謝您將這引起我的注意。你的log4perl傢伙,邁克。

0

從文檔在http://search.cpan.org/dist/Log-Log4perl/lib/Log/Log4perl.pm

從系統中刪除記錄,使用日誌:: Log4perl-> remove_logger($記錄器)。在剩餘的參考$記錄器消失後,記錄器將自毀。如果所述記錄器是隱形記錄器,則其所有便捷快捷鍵(DEBUG,INFO等)將變爲空操作。

+0

嘿。如果您閱讀其他答案,則此功能是此問題的後果。我其實很自豪。 :-) – BlairHippo 2011-12-02 16:58:28