2015-11-02 2 views
1

Я использую MIC для моего кеша LRU на сервере, он заменил LRU с номером/картой, так как я подозревал, что именно это и вызвало некоторый необъяснимый объем памяти. Утечки памяти не соответствуют действительности, по крайней мере, ни один инструмент не обнаружил утечки, а также проверки кода. Поскольку я начал использовать MIC, изображение улучшилось (это единственный доказательство фрагментации памяти), но недостаточно. Мы говорим о нескольких ГБ кеша, из которых миллионы записей излагаются ежедневно. Через две-три недели проблема становится очевидной - если я выпущу кеш, процесс все еще содержит необъяснимые 2-3 ГБ памяти.
Мой контейнер довольно просто:boost multi_index_container и фрагментация памяти

typedef std::pair<Key, T> Element; 
    typedef mic::multi_index_container< 
     Element, 
     mic::indexed_by<mic::sequenced<mic::tag<struct Seq>>, 
         mic::hashed_unique<mic::tag<struct Hash>, mic::member<Element, const Key, &Element::first>>>> 
     item_list; 

использует erase и push_front вставить новую запись (или переписать старый), а затем, если это необходимо выталкивает элемент из хвоста. Вопрос в том, стоит ли использовать replace и relocate вместо push_front?

UPDATE001: Хорошо, новая версия запущена и работает, я вижу, что эта функция значительно улучшила ситуацию, объем памяти после 3 недель был на 1/1,5 Гб ниже, чем на машинах без изменений. Теперь он развернут на всех машинах по всему миру. На втором этапе существует множество изменений в механизмах недействительности кеша. Меньше эжекций и повторных вставок также должно улучшить ситуацию (в случае, если это действительно фрагментация памяти)

+0

просто спрашивает - знаете ли вы, как malloc/free work, и почему это не имеет значения, что память процесса никогда не выпускается после выделения? –

+0

Не имеет значения, как работает функция alloc/free, так как они не отвечают за распределение/освобождение памяти, диспетчер памяти ОС. В этом конкретном случае VirtualAllocEx будет задействован, решив, сколько памяти будет выделено (да, даже если это не выполняется с помощью alloc), и, действительно, бесплатно не гарантируют, что память будет фактически выпущена обратно в ОС. однако вы можете заставить ОС восстановить освобождение, но не отпустить обратно в память ОС \ – kreuzerkrieg

+0

правильно ... так почему вы удивлены тем, что объем памяти в процессе не падает? Или я не понимаю проблему? –

ответ

0

Мы испытали то же самое. Я написал небольшую тестовую программу, которая использует наш кеш из 300 потоков. Он держит insert ing и erase ing примерно в 200k (insert + erase)/sec, и я провел его в выходные дни. я исследовал использование памяти с помощью PMAP -x общего RSS

pmap -x [pid] | tail -n1 | awk '{print $4}' 

В одну минуту разрешение, можно увидеть, что, пока кэш не будет загружен потребление памяти ~ линейный от 0 до 4.7GB, и после того, что это когда-либо увеличивающихся с логарифмической скоростью. Как показано на рисунке. (Для завершения кеша потребовалось 14 минут). enter image description here

Еще одна интересная вещь, что ртар -x сообщили много 65536k куски виртуальной памяти, которые были загружены получать (так что может быть theoritical максимум для этого чрезмерного использования памяти), но если бы я сделал то же самое из одного потока тестовая программа выделила один блок объемом 4,7 ГБ и после того, как кеш был заполнен, использование памяти было постоянным.

+0

Кстати, мы вообще отказались от материала LRU и переключились на unbounded_map. Ну, мы не слишком далеки от проблем управления памятью. Посмотрите здесь http://stackoverflow.com/questions/39313820/stdunordered-map-does-not-release-memory – kreuzerkrieg

 Смежные вопросы

  • Нет связанных вопросов^_^