在啓用了可選ICU支持的情況下使用boost regex類時(詳情請參見boost documentation),我似乎得到了內存泄漏或者某種內存緩存,我無法似乎重置/清理。在Win32上使用icu u32_regex內存泄漏/緩存提升
有沒有其他人看到這個,也許知道一種清除緩存的方式,以便增強單元測試框架不會報告內存泄漏?
我的問題的細節是: -
ICU version 4.6.0
(Built using supplied vs2010 solution in debug and release configuration)
Boost version 1.45
(built with command "bjam variant=debug,release threading=multi link=shared stage" since standard distribution does not include icu support in regex)
OS Windows 7
Compiler MSVC 10 (Visual Studio 2010 Premium)
雖然我沒有嘗試這個具有提升1.42與ICU 4.2.1我碰巧已經建立了與我相同的結果,系統上,因此不認爲它的一個問題,將通過改變以提升1.47 icu 4.8.1這是最新版本來解決。
編譯以下代碼(Test.cpp的): -
#define BOOST_TEST_MAIN //Ask boost unit test framework to create a main for us
#define BOOST_ALL_DYN_LINK //Ask boost to link to dynamic library rather than purely header support where appropriate
#include <boost/test/auto_unit_test.hpp>
#include <boost/regex.hpp>
#include <boost/regex/icu.hpp> //We use icu extensions to regex to support unicode searches on utf-8
#include <unicode/uclean.h> //We want to be able to clean up ICU cached objects
BOOST_AUTO_TEST_CASE(standard_regex)
{
boost::regex re("\\d{3}");
}
BOOST_AUTO_TEST_CASE(u32_regex)
{
boost::u32regex re(boost::make_u32regex("\\d{3}"));
u_cleanup(); //Ask the ICU library to clean up any cached memory
}
其可以從一個命令行由被編譯: -
C:\>cl test.cpp /I[BOOST HEADERS PATH] /I[ICU HEADERS] /EHsc /MDd -link /LIBPATH:[BOOST LIB PATH] [ICU LIB PATH]icuuc.lib
隨着用於頁眉/庫的適當路徑的機器
將適當的boost dll複製到包含test.exe的目錄中,如果它們沒有在(boost_regex-vc100-mt-gd-1_45.dll和boost_unit_test_framework-vc100-mt-gd-1 _45.dll)
當test.exe的從上面的步驟運行我得到: -
Running 2 test cases...
*** No errors detected
Detected memory leaks!
Dumping objects ->
{789} normal block at 0x00410E88, 28 bytes long.
Data: < 0N U > 00 00 00 00 30 4E CD 55 00 00 00 00 01 00 00 00
{788} normal block at 0x00416350, 14 bytes long.
Data: <icudt46l-coll > 69 63 75 64 74 34 36 6C 2D 63 6F 6C 6C 00
{787} normal block at 0x00415A58, 5 bytes long.
Data: <root > 72 6F 6F 74 00
...lots of other blocks removed for clarity ...
我猜ICU實際上是罪魁禍首在這裏,因爲那裏有它的名字在的開始第二個街區。
只是做第一次測試(即只是創建一個標準的正則表達式不是u32_regex)沒有檢測到內存泄漏。
將多個u32_regex添加到測試不會導致更多的內存泄漏。
我試圖按照icu documentation使用u_cleanup()調用清理icu緩存,參見ICU初始化和終止部分。
但是我對icu庫不是很熟悉(實際上只是使用它,因爲我們想要unicode瞭解正則表達式支持),並且無法看到如何在ICU是實際清理數據時獲得u_cleanup()調用來實際清理數據由boost正則表達式DLL加載。
只是爲了重申這個問題似乎是: -
與可選的ICU支持編譯一個dll升壓正則表達式(我敢肯定,這個使用靜態鏈接到重症監護病房,但可能是錯在這裏)
如果我在測試程序中鏈接到icuuc.lib,以便我可以調用u_cleanup(),這似乎不會影響ICU實例通過boost正則表達式庫加載的內存(如果它確實如此)
我找不到正則表達式庫中的任何調用,它允許我要求它清理ICU數據,它真的是我們想要的數據歡迎來電。
謝謝 - 這只是泄露數據的開始 - 我已經編輯了希望更清晰的問題。 –
進一步調查表明,icu實際上是動態鏈接而不是靜態鏈接。 Boost正則表達式似乎優雅地退化,如果沒有找到icu dll,這就是爲什麼刪除icu dll不會生成dll找不到消息(這是我的簡單測試,看看動態或靜態鏈接)。因此,u_cleanup()應該可以工作(我認爲) –
如果您構建的ICU的預處理器標誌UCLN_NO_AUTO_CLEANUP定義爲0(您可以在uconfig.h的頂部添加一個#define),那麼ICU將在卸載DLL時清除自身。如果ICU已被清理或永不加載,則u_cleanup可以安全調用。 –