У меня есть набор программ, работающих совместно с общей памятью (ipc) ~ 48 ГБ.Устранение утечек памяти без valgrind
программы, работающая в Linux 3.6.0-RC5, написанный простым С, составленный GCC средней нагрузки на главном компьютере 6,0 прыгает 16,0 каждые 10 секунд (24 ядер)
Один прокси принимает данные от других машин по 0mq (3.2.3, ~ 1000 msgs/s из 12 машин в одной сети), запись в разделяемую память Многие (< 50) работники считывают эти данные и выполняют некоторые вычисления.
Прокси-сервер, использующий около 20% процессора Каждый рабочий, использующий 1% процессор, прыгает на 10% периодически.
Все программы написаны таким образом, когда все распределения сделано в Init() - вызывается при запуске программы, все бесплатно сделано уничтожить() - вызывается перед выходом
Серийное код не используя любой таНос/calloc/бесплатно на всех ,
Но обе программы все еще протекают. Около 120-240 байт в минуту. Это не так много - память исчерпана за 7-8 дней, и я просто запускаю/останавливаю процесс, но те просочившиеся байты едят мой разум каждый раз, когда приложение мониторинга сообщает мне об этом перезагрузке :)
Плохие вещи - я не могу запустить valgrind из-за использования разделяемая память - ее просто останавливается при распределении/подключении разделяемой памяти, а затем все начинает раздавливаться.
Пытаясь найти эту утечку, я сделал разделенную версию прокси - никаких утечек, но я не могу ее подавать с таким же количеством данных.
При работе под gdb по-прежнему нет утечек, но скорость снижается примерно на 2/3 - поэтому может быть не так быстро воспроизвести эту ошибку.
Так возможные утечки в:
- мой код. но нет malloc/calloc. Просто указатели + -, memcpy, memcmp
- некоторые стандартные библиотеки. GLibC? системный журнал?
- 0mq работать со многими источниками (не думаю, что 1к/сообщ за секунды слишком много трафика)
ли какие-либо другие инструменты/LIBS/хаки существует, что может помочь в такой ситуации?
Редактировать: Шиван Раптор спросил о коде. Повторяющаяся часть - 5k строк математики. Без каких-либо ассигнований, как я упоминал.
Но старт, стоп и повторяющийся ввод здесь:
int main(int argc, char **argv)
{
ida_init(argc, argv, PROXY);
ex_pollponies(); // repetive
ida_destroy();
return(0);
}
// with some cuttings
int ex_pollponies(void)
{
int i, rc;
unsigned char buf[90];
uint64_t fos[ROLLINGBUFFERSIZE];
uint64_t bhs[ROLLINGBUFFERSIZE];
int bfcnt = 0;
uint64_t *fo;
uint64_t *bh;
while(1) {
rc = zmq_poll(ex_in->poll_items, ex_in->count, EX_POLL_TIMEOUT);
for (i=0; i < ex_in->count; i++) {
if (ex_in->poll_items[i].revents & ZMQ_POLLIN) {
if (zmq_recv(ex_in->poll_items[i].socket, &buf, max_size, 0) == 0)
continue;
fo = &fos[bfcnt];
bh = &bhs[bfcnt];
bfcnt++;
if (bfcnt >= ROLLINGBUFFERSIZE)
bfcnt = 0;
memcpy(fo, (void *)&buf[1], sizeof(FRAMEOBJECT));
memcpy(bh, &buf[sizeof(FRAMEOBJECT)+1], sizeof(FRAMEHASH));
// then store fo, bh into shared memory, with some adjusting and checkings
// storing every second around 1000 msgs 16 bytes each. But leaking is only 200 bytes per minute.
}
}
}
}
edit2:
я, наконец, сделать VALGRIND работу - просто сделать использование часть данных (6GB) и, наконец, прошел. И не обнаруживайте утечек. Но по мере работы он берет 100% -ный процессор и определенно моя программа не обрабатывает все входящие данные - она не работает при полной нагрузке. Эта половина подтвердила мое предположение о lasthope - утечка находится на блоке обмена данными. Я нахожу информацию о mtrace (часть libc) Это помогло мне отслеживать ADDRESS утечки - вне моего кода, в одном из потоков. Единственные потоки в моем коде создаются zeromq.Затем я начинаю играть с опциями для сокетов (увеличение hwm, буферов), а скорость утечки уменьшилась, но не полностью ушла даже по абсурдно большим значениям :(
Итак, теперь я на 95% уверен, что его нулевой уровень протекает. . в их списке почты
где ваш код? – Raptor
Посмотрите документацию по функциям библиотеки, которые вы используете. Кто-нибудь из них выделяет вам память и ожидает, что вы ее освободите? – Shahbaz
Что заставляет вас думать, что есть утечка? Статистика может вводить в заблуждение. если вы выделите память на init и коснитесь ее только позже, страницы будут выделены только при касании, что выглядит как выделение. – ugoren