повысить с помощью icu u32_regex утечка памяти / кеш на Win32 - PullRequest
3 голосов
/ 29 июля 2011

При использовании класса boost regex с включенной опциональной поддержкой ICU (подробности см. boost документация ), похоже, возникает утечка памяти или, скорее, происходит какое-то кэширование памяти, которое я не могу сбросить / cleanup.

Кто-нибудь еще видел это и, возможно, знает способ очистки кэша, чтобы инфраструктура тестового модуля повышения не сообщала об утечке памяти?

Детали моей проблемы: -

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 в каталог, содержащий 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 на самом деле является виновником, так как там у него есть имя в начале 2-го блока.

Простое выполнение 1-го теста (т.е. создание стандартного регулярного выражения, а не u32_regex) не обнаруживает утечек памяти.

Добавление нескольких u32_regex в тест не приводит к утечке памяти.

Я попытался очистить кеш icu с помощью вызова u_cleanup () согласно документации icu , см. Раздел Инициализация и завершение ICU.

Однако я не очень знаком с библиотекой icu (на самом деле я использую ее только потому, что нам нужна была поддержка регулярных выражений с поддержкой юникода) и не могу понять, как получить вызов u_cleanup () для фактической очистки данных во время работы ICU загружается буст-регулярным выражением dll.

Просто для повторения проблема выглядит так: -

boost regex в dll, скомпилированной с дополнительной поддержкой icu (я почти уверен, что здесь используется статическая ссылка на icu, но здесь может быть ошибка)

Если я свяжусь с icuuc.lib в тестовой программе, чтобы я мог вызвать u_cleanup (), это, по-видимому, не повлияет на память, хранящуюся в экземпляре ICU, загруженном через библиотеку регулярных выражений boost (ну, это было бы довольно странно, если это сделал)

Я не могу найти какие-либо вызовы в библиотеке регулярных выражений, которые позволили бы мне попросить ее очистить данные ICU, именно там мы и хотим сделать вызов.

Ответы [ 2 ]

1 голос
/ 12 августа 2011

Просто подумал, что я также могу ответить на вопрос здесь, так как решил (с помощью активных пользователей).

Проблема в следующем порядке: если статические объекты в dll boost regex не будут уничтожены до каркаса модульного теста, тогда они все равно будут кэшировать некоторые данные. И поэтому UTF сообщает об утечках памяти. Простого вызова u_cleanup () недостаточно.

Самый простой способ обеспечить порядок - связать с платформой модульного тестирования как статическую библиотеку - тогда ее объекты разрушаются после любых dll и поэтому не сообщает о кешированных объектах как утечка памяти, поскольку они уже разрушены .

1 голос
/ 29 июля 2011

u_cleanup - это то, что очищает данные, однако не может очистить данные, если какие-либо элементы все еще открыты.

Можете ли вы попробовать не вызывать какую-либо функцию повышения, а просто вызывать u_cleanup ()и посмотреть, есть ли утечки?А затем попробуйте просто позвонить u_init(), а затем u_cleanup()

Я не знаком с Boost, чтобы знать, очистит ли приведенный выше код регулярное выражение или если в boost есть какое-либо внутреннее кэширование.Утечка объектов не похожа на обычные данные ICU, если бы данные ICU оставались открытыми, вы бы увидели довольно много данных, а не 14 + 5 байт

...