утечка памяти - PullRequest
       9

утечка памяти

1 голос
/ 21 июня 2011

У меня есть класс C ++, который записывает свои данные в двоичный файл std::ofstream.Класс хранит данные как boost:shared_array, но я устранил это как проблему.Проблема с вызовом write() на ofstream.

Проблема в том, что, похоже, происходит утечка памяти.Система, на которой он работает, - это CentOS 64bit, GCC 4.1.2.

При просмотре top и free, когда приложение работает, сам исполняемый файл не продолжает потреблять память (поскольку выполняетсяпрофилировщик памяти в Netbeans), но объем свободной системной памяти со временем уменьшается.Более того, , когда приложение выходит из этой памяти, не освобождается!

Это особая проблема, поскольку предполагается непрерывная запись на диск со скоростью около 50 МБ / с в течение нескольких часов подряд.Однако, как только мы освобождаем около 90 МБ свободной системной памяти, она, похоже, «стабилизируется» и больше не сокращается, и приложение продолжает работать нормально.Тем не менее, он портит систему для других запущенных процессов, что плохо, ммкей.

Ниже приведена очень упрощенная версия класса, вызывающая горе.

class WritableMessage
{
public:
    WritableMessage();
    void write(std::ofstream* const idxStream, std::ofstream* const dataStream);

private:
    IdxRecord m_idx;
    boost::shared_array<char> m_data;
};

Исходные потоки инициализируются и разрушаются в другом месте, но по существу они остаются открытыми для написания «навсегда».

void WritableMessage::write(std::ofstream* const idxStream, std::ofstream* const dataStream)
{
    //Call the IdxRecord to write itself (just a call to idxStream->write())
    m_idx.write(idxStream, dataStream->tellp());

    //This is the main issue, because this data can be up to about 2MB in size
    //for each write.  Commenting out this line removes all issues with the memory leak
    dataStream->write(m_data.get(), m_idx.getMessageSize());

    //I'd expect the flush to clear any buffers that the ofstream maintains,
    //but apparently not
    idxStream->flush();
    dataStream->flush();
}

Ответы [ 2 ]

4 голосов
/ 21 июня 2011

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

3 голосов
/ 21 июня 2011

Использовать vmstat ( man-страница )

vmstat -S m 1

Это покажет вам кэш и буферную память.Обратите внимание, что буферная память является энергозависимой и будет автоматически освобождена, как только приложение запросит ее.

Я могу легко показать эффект на моем рабочем столе 8 ГБ (linux), войдя в систему и просто выполнив команду 'dd if = /dev / sda of = / dev / null ';буферная память будет постоянно потреблять всю доступной памяти.

Это предусмотрено

Некоторые соответствующие ссылки:

...