Очищение памяти...

fedotxxl

Well-known member
09.11.2005
614
0
#1
Кто-нибудь задавался вопросом правильно очищения памяти после исполнения метода (Delete....)?

Пример: у меня есть класс A, в классе private переменные notesdatabase которые можно забрать через функцию getMyDb (например). Если в функции исполнить такой код
Код:
dim myClass as new A
Set db = myClass.getMyDb
Delete db
то также удалится private переменная notesdatabase... как победить?
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#2
значит БД нужно обьявить глобально или передавать её в процедуру, где она и оформится
 
Y

Yakov

#3
Правильно будет вообще не пользоваться Delete (*). :) Как только исполнение кода выйдет из области видимости переменной, она будет уничтожена.
----
* Кроме особых случаев, вроде считывания файлов в память в цикле.
 

nvyush

Lotus team
22.04.2009
2 317
0
#4
Пример: у меня есть класс A, в классе private переменные notesdatabase которые можно забрать через функцию getMyDb (например). Если в функции исполнить такой код
Код:
dim myClass as new A
Set db = myClass.getMyDb
Delete db
то также удалится private переменная notesdatabase... как победить?
Set db = ... создает новую ссылку на имеющийся объект db. Delete нужен для уничтожения объектов, созданных new, т.е. после
dim ... as new ...
set ... = new ...

Delete неявно вызывается при выходе из процедуры, где создан объект.
В приведенном примере похоже нужно вместо delete db использовать set db = Nothing.
 

fedotxxl

Well-known member
09.11.2005
614
0
#5
nvy
Пасиба, возможно

В теории память должна очищаться после исполнения функци... Но у меня память линейно растет в процессе исполнения агента, что быть не должно
 

TIA

:-)
Lotus team
15.05.2009
790
3
#6
Но у меня память линейно растет в процессе исполнения агента, что быть не должно
Нет ли кэшей, например, открытых документов, баз, вьюх?
Delete зачастую можно заменить присвоением Nothing.

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

Yakov

#7
fedotxxl, каким образом вы измеряете потребление памяти?
Я когда-то тестировал расход памяти для различных структур, используя Lsi_info. Так вот, даже при принудительном удалении массивов и списков память росла до некоторого предела, потом Лотус ее освобождал. То есть, возврат памяти Лотусом в операционную систему не связан с вызовом Delete в LS. Оно и правильно, в Лотусе наверняка какой-нибудь очень хитрый менеджер памяти есть.
Если у вас клиент или сервер не падают при работе агента, то и беспокоиться не стоит.
Можно еще попробовать прогонять в агенте те же данные несколько раз и посмотреть, будет ли освобождаться память.
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#8
Правильно будет вообще не пользоваться Delete (*). Как только исполнение кода выйдет из области видимости переменной, она будет уничтожена.
----
* Кроме особых случаев, вроде считывания файлов в память в цикле.
не хочу спорить, но по опыту это не всегда так или несовсем так, часто замечал что память течет там где уже не должна(на сервере из задач только агент менеджер)

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

Есть подозрение что "правильность" суждения о том, что переменные схлопываются после завершения процедуры лишь начиная с 8.0.2 так как именно с этой версии ИБМ начал заявлять что память больше не течет..
 

fedotxxl

Well-known member
09.11.2005
614
0
#9
Если у вас клиент или сервер не падают при работе агента, то и беспокоиться не стоит.
а если валится?

В итоге я понял следующее:
1. Если переменная используется только внутри класса / метода - delete в нужно месте
2. Если переменная может передаваться во внешние функции - nothing

Yakov
Подскажи, пожалуйста, которая из Lsi_info возвращает объем использованной памяти?
 
13.03.2009
625
1
#10
Подскажи, пожалуйста, которая из Lsi_info возвращает объем использованной памяти?
Забанили в гугле? Тогда мы идем к Вам :)
http://www.google.com/search?hl=en&hs=...mp;oq=&aqi=
Первая ссылка: http://www.codestore.net/store.nsf/cmnts/1...6F?OpenDocument
lsi_info(50) = LS memory allocated
lsi_info(51) = LS memory allocated from OS
lsi_info(52) = LS blocks used
 
Y

Yakov

#12
По-моему, LS memory allocated from OS - память, которую Lotus "взял" у ОС (столбец "Память" в Task Manager'е), LS memory allocated - память, которую Lotus уже использует, LS blocks used - количество блоков использованной памяти (Lotus выделяет и освобождает память блоками размером (LS memory allocated) / (LS blocks used)).
 

fedotxxl

Well-known member
09.11.2005
614
0
#13
Yakov
Теже .... только в профиль...
Мне нужно корректно измерить сколько памяти сожрал агент (можно в относительных еденицах). Которую функцию мне использовать?

Потестировал очищение памяти, у меня получилось что:
1. Метод delete в классе можно не определять
2. Достаточно делать все delete (не забывать делать delete в цикле)
3. Использование delete замедляет исполнение агента на 10-20%
 

nvyush

Lotus team
22.04.2009
2 317
0
#14
Yakov
Потестировал очищение памяти, у меня получилось что:
1. Метод delete в классе можно не определять
2. Достаточно делать все delete (не забывать делать delete в цикле)
3. Использование delete замедляет исполнение агента на 10-20%
Все ли создания объектов нужны внутри цикла? Может что-то можно вынести наружу, например:
<!--shcode--><pre><code class='LotusScript'>While ...
Set s = new NotesSession
Set db = s.CurrentDatabase
....
delete s
wend[/CODE]
будет явно работать дольше, чем
<!--shcode--><pre><code class='LotusScript'>Set s = new NotesSession
While ...
Set db = s.CurrentDatabase
....
wend
delete s[/CODE]
 
Y

Yakov

#15
Я бы попробовал измерить и сравнить 4 величины: использование памяти (lsi_info(50)) до запуска агента (в коде, запускающем агент), в начале работы агента (в коде агента), в конце работы агента (в коде агента), после завершения работы агента (в коде, запускающем агент после Delete agent).
 

fedotxxl

Well-known member
09.11.2005
614
0
#16
nvy
Ясень пень так. Просто иногда нужно внутри цикла инициировать объект

Yakov
Сегодня днем поищу в инете инфу по этому поводу