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

  • Автор темы Itar
  • Дата начала
I

Itar

#1
Добрый день!
Проблема заключается в следующем: нужно написать агент, который будет опрашивать lotus сервера и считывать через определенные промежутки времени некоторые значения из базы данных. После запуска программы она разрастрается в памяти. Подскажите в чем может быть проблема?
Ниже приводится код программы, которая разрастается
C++:
#include <iostream.h>
#include <lncppapi.h>
#define ERR_BUF_SIZE 512
void main()
{
LNNotesSession	Session;
LNDatabase	Db;
LNString DbTitle;
while(true)
{
try
{
Session.Init();
Session.GetDatabase("Mail.box", &Db,"Test01");
Db.Open();
DbTitle = Db.GetTitle();
cout<<DbTitle<<endl;
}
catch (LNSTATUS Lnerror)
{
char ErrorBuf[ERR_BUF_SIZE];
LNGetErrorMessage(Lnerror, ErrorBuf, ERR_BUF_SIZE);
cout << "Error: " << ErrorBuf << endl;
}
Db.Close();
Session.Term();
Sleep(5000);
}
}
 

vital

Больной Компом Детектед
29.01.2006
2 432
33
#2
1. Это не тот топик для этой темы.
2. Само собой, что она разрастается в памяти!
Вместо бесконечного цикла используйте таймер с интервалом в 5 сек.! И все будет нормально.
 
I

Itar

#3
Там в конце цикла стоит Sleep(5000), можно поставить задержку и больше, но программа все равно будет разрастаться
 
04.09.2006
2 566
3
#4
Течет где-то внутри Лотуса... Возможно, нужны какие-то дополнительные вызовы для деинициализации объектов. Может LNString тоже нужно "закрывать".
P.S. Перемещу-ка я вашу тему к Лотусистам, может там вам быстрее подскажут
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#5
я уже давно не прогал на сях, но локальная переменная в цикле... и воще жрёт стек
вот ругань на подобные "фокусы"
http://www.xakep.ru/magazine/xa/117/116/1.asp
непонятен "фокус" с закрытием сессии - это ещё зачем?
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#7
char ErrorBuf[ERR_BUF_SIZE];
 
I

Itar

#8
Может LNString тоже нужно "закрывать".
Попробывал без этой переменной, все равно разрастается

непонятен "фокус" с закрытием сессии - это ещё зачем?
Это на случай, если сервер лежит
Но там правильно надо писать
Код:
if (Session.IsInitialized ()) Session.Term();
Утечек при открытии и закрытии сессия нет, они появляются при работе с бд

Пробывал прогонять через Deleaker программы-примеры, котооые идут вместе с библиотеками Lotus для с++, он тоже показывает утечки. Но мне кажется странным, что IBM до сих пор это не исправил, я пользуюсь 8-ой версией библиотеки.
 
04.09.2006
2 566
3
#9
Так она же в обработчике исключительной ситуации, которой может и не быть. И будет удалена при выходе из обработчика. Тут все ОК

Добавлено:
Пробывал прогонять через Deleaker программы-примеры, котооые идут вместе с библиотеками Lotus для с++, он тоже показывает утечки.
Вот и ответ ;)
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#11
Так она же в обработчике исключительной ситуации, которой может и не быть. И будет удалена при выходе из обработчика. Тут все ОК

Добавлено:
Вот и ответ ;)
нет не всё ок ;)
зачем там локальный буфер, на стеке, да ещё 512 байт...
строка туда попадет терминированная
а вот выделение памяти, при срабатывании эксепшена - совершенно не нужно, статик вполне подходит

а вот заворачивание стека - вполне может привести к утечкам, и чем меньше мы в него пихнем (а уж буферов - точно), тем устойчивее будет
 
I
#12
Я смотрю размер программы по диспетчеру задач, может он врет?
 
04.09.2006
2 566
3
#14
зачем там локальный буфер, на стеке, да ещё 512 байт...
Чтобы перевести лотусиную строку в сишную
а вот заворачивание стека - вполне может привести к утечкам
Но не в это случае
Я смотрю размер программы по диспетчеру задач, может он врет?
Он показывает не размер выделенной вашим кодом памяти. Подробности есть здесь: http://gunsmoker.blogspot.com/2009/05/blog-post_24.html.
Если желаете разобраться в деталях, то в статье есть 2 ссылки Марка Руссиновича
 

TIA

:-)
Lotus team
15.05.2009
790
3
#15
У Нотеса есть кэши открытых БД. Потому первоначальный рост используемой виртуальной памяти вполне обоснован. Попробуйте погонять ваш цикл подольше, чтобы кэши полностью заполнились или уже нечего было в них помещать. После этого и анализируйте утечки. Таскменеджеру не верьте, особенно для больших значений VM. Используйте PerfomanceMonitor, встроенный в винды (ControlPanel\AdministrativeTools\Perfomance). Он показывает точные данные, позволяет строить графики и наглядно посмотреть оценить утечки.

Добавлено:
Он показывает не размер выделенной вашим кодом памяти.
Так однозначно сложно утверждать, т.к. можно добавить колонку с виртуальной памятью.
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#16
Чтобы перевести лотусиную строку в сишную
...
Но не в это случае
ключевые слова - "на стеке", а не "зачем буфер"

вы знаете какой размер стека выделяется и в каких случаях и на каких платформах, и сколько уже отъедено процессом,
вложенность вызовов...?;)

теперь представим, что в таком стиле (не используя статики для буферов, или кучу, а пихая их в стек) пишут и другие проггеры
есть оригиналы - туды и объекты пихают...
а потом удивляемся непредсказуемости софта

пропуская лирику... - обозначить буфер статиком, я полагаю, "религия" никому не мешает ;)
 

TIA

:-)
Lotus team
15.05.2009
790
3
#17
пропуская лирику... - обозначить буфер статиком, я полагаю, "религия" никому не мешает
Религия религией, но к данному вопросу об утечках она имеет отстранённое отношение, т.к. переменные на стеке выделяются при входе в область видимости. В данном случае, память стековая память под ErrorBuf выделится только при срабатывании catсh.
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#18
есть стиль программирования
вот буфера на стэке - порочная, глюкопроизводящая составляющая
просто переменные - да пусть с ними (это нормально), а буфера - это через край
ну представьте - случился кэтч, стек завернулся (очередной умелец, в вызывающих ф-циях его также и "выжрал") и чё поимеем - гимор!

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

TIA

:-)
Lotus team
15.05.2009
790
3
#19
у представьте - случился кэтч, стек завернулся (очередной умелец, в вызывающих ф-циях его также и "выжрал") и чё поимеем - гимор!
Замечу, что в момент отработки catch'а в вызывающих функциях стек, занятый вызываемыми, уже освободится.
 
K

K-Fire

#20
А сколько конкретно памяти то утекает? А то может ради пары сотен килобайт не стоит и возиться.