Информация об изменениях

Сообщение Re: Узнать что потребляет "лишнюю" память от 27.11.2014 3:00

Изменено 27.11.2014 3:05 omgOnoz

Здравствуйте, kFk, Вы писали:

  Скрытый текст
kFk>Никак не могу разобраться, что в приложении потребляет лишнюю память.

kFk>Из чего строю предположения о "лишней" памяти:


kFk>1) Загружаю ряд текстур, в памяти они занимают 140мб. При этом потребление памяти увеличивается на 170мб. Итого 30мб overhead.


kFk>2) Загружаю из xml множество строк, записываю их во что-то вроде std::vector<std::pair<std::string, std::string>>.

kFk>Дальше вручную считаю сколько должно занять памяти. Для вектора считаю так:
kFk>
auto size = sizeof(v) + v.capacity() * sizeof(T);
kFk>for (const auto& element : v)
kFk>{
kFk>  size += TotalSizeOf(element) - sizeof(T);
kFk>}
kFk>return size;

kFk>Каждую строку считаю так:
kFk>
return sizeof(s) + s.capacity() * sizeof(std::string::value_type);

kFk>Посчитанная память и выделенная почти полностью совпадают.

kFk>3) Загружаю приложение(игру) целиком. Таким же образом как и в прошлом пункте считаю потребляемую память везде, где возможно (поэлементно рекурсивно все контейнеры, раскрываю все смарт-поинтеры, память текстур, ...).

kFk>Посчитанная таким образом память — 243мб текстур + 7мб на все остальное. Реально выделенная — 350мб. Итого неизвестно куда уходят 100мб. Главная цель — понять что занимает эти злополучные 100мб.

kFk>Память мерял через:

kFk>- Windows: Private Bytes в Process Explorer от Русиновича
kFk>- Windows
kFk>
PROCESS_MEMORY_COUNTERS_EX pmc;
kFk>GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
kFk>return pmc.PrivateUsage;
kFk>

kFk>- iOS
kFk>
struct task_basic_info info;
kFk>mach_msg_type_number_t size = sizeof(info);
kFk>kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
kFk>return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes


kFk>Утечек нет или они минимальные, т.к. при многократной выгрузке и загрузке общая картина почти не меняется.

kFk>Ситуация под Windows и iOS аналогичная. Пробовал профилировать память в Xcode Instruments, но безрезультатно.

kFk>Помогите, а?

kFk>Заранее огромная благодарность за любые подсказки.


А не пробовал смотреть в какой момент лишняя память сжирается? Вот есть подозрения на подгружаемые ресурсы — для теста попробуй их не подгружать
Единственный нормальный способ — это изолировать компоненты приложения — некое подобие юнит тестов.
Здравствуйте, kFk, Вы писали:

  Скрытый текст
kFk>Никак не могу разобраться, что в приложении потребляет лишнюю память.

kFk>Из чего строю предположения о "лишней" памяти:


kFk>1) Загружаю ряд текстур, в памяти они занимают 140мб. При этом потребление памяти увеличивается на 170мб. Итого 30мб overhead.


kFk>2) Загружаю из xml множество строк, записываю их во что-то вроде std::vector<std::pair<std::string, std::string>>.

kFk>Дальше вручную считаю сколько должно занять памяти. Для вектора считаю так:
kFk>
auto size = sizeof(v) + v.capacity() * sizeof(T);
kFk>for (const auto& element : v)
kFk>{
kFk>  size += TotalSizeOf(element) - sizeof(T);
kFk>}
kFk>return size;

kFk>Каждую строку считаю так:
kFk>
return sizeof(s) + s.capacity() * sizeof(std::string::value_type);

kFk>Посчитанная память и выделенная почти полностью совпадают.

kFk>3) Загружаю приложение(игру) целиком. Таким же образом как и в прошлом пункте считаю потребляемую память везде, где возможно (поэлементно рекурсивно все контейнеры, раскрываю все смарт-поинтеры, память текстур, ...).

kFk>Посчитанная таким образом память — 243мб текстур + 7мб на все остальное. Реально выделенная — 350мб. Итого неизвестно куда уходят 100мб. Главная цель — понять что занимает эти злополучные 100мб.

kFk>Память мерял через:

kFk>- Windows: Private Bytes в Process Explorer от Русиновича
kFk>- Windows
kFk>
PROCESS_MEMORY_COUNTERS_EX pmc;
kFk>GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
kFk>return pmc.PrivateUsage;
kFk>

kFk>- iOS
kFk>
struct task_basic_info info;
kFk>mach_msg_type_number_t size = sizeof(info);
kFk>kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
kFk>return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes


kFk>Утечек нет или они минимальные, т.к. при многократной выгрузке и загрузке общая картина почти не меняется.

kFk>Ситуация под Windows и iOS аналогичная. Пробовал профилировать память в Xcode Instruments, но безрезультатно.

kFk>Помогите, а?

kFk>Заранее огромная благодарность за любые подсказки.


А не пробовал смотреть в какой момент лишняя память сжирается? Вот есть подозрения на подгружаемые ресурсы — для теста попробуй их не подгружать
Единственный нормальный способ — это изолировать компоненты приложения — некое подобие юнит тестов.

Как написали выше — вполне может быть ддл, которая пишет для себя кеш для быстрой загрузки ресурсов, ты вот загружаешь и выгружаешь многократно — а оно 1 раз записало в кеш и дергает его, вот память после первой загрузки практически не меняется.