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

  • Автор темы Автор темы fedotxxl
  • Дата начала Дата начала
F

fedotxxl

Кто-нибудь задавался вопросом правильно очищения памяти после исполнения метода (Delete....)?

Пример: у меня есть класс A, в классе private переменные notesdatabase которые можно забрать через функцию getMyDb (например). Если в функции исполнить такой код
Код:
dim myClass as new A
Set db = myClass.getMyDb
Delete db
то также удалится private переменная notesdatabase... как победить?
 
значит БД нужно обьявить глобально или передавать её в процедуру, где она и оформится
 
Правильно будет вообще не пользоваться Delete (*). :) Как только исполнение кода выйдет из области видимости переменной, она будет уничтожена.
----
* Кроме особых случаев, вроде считывания файлов в память в цикле.
 
Пример: у меня есть класс 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.
 
nvy
Пасиба, возможно

В теории память должна очищаться после исполнения функци... Но у меня память линейно растет в процессе исполнения агента, что быть не должно
 
Но у меня память линейно растет в процессе исполнения агента, что быть не должно
Нет ли кэшей, например, открытых документов, баз, вьюх?
Delete зачастую можно заменить присвоением Nothing.

LS также не любит большое число взаимосвязанных LS-объектов (своих, а не классов Notes...). Он оставляет их очистку до выгрузки агента, что наблюдается длительным интервалом между самым последним оператором агента и его завершением агента.
 
fedotxxl, каким образом вы измеряете потребление памяти?
Я когда-то тестировал расход памяти для различных структур, используя Lsi_info. Так вот, даже при принудительном удалении массивов и списков память росла до некоторого предела, потом Лотус ее освобождал. То есть, возврат памяти Лотусом в операционную систему не связан с вызовом Delete в LS. Оно и правильно, в Лотусе наверняка какой-нибудь очень хитрый менеджер памяти есть.
Если у вас клиент или сервер не падают при работе агента, то и беспокоиться не стоит.
Можно еще попробовать прогонять в агенте те же данные несколько раз и посмотреть, будет ли освобождаться память.
 
Правильно будет вообще не пользоваться Delete (*). Как только исполнение кода выйдет из области видимости переменной, она будет уничтожена.
----
* Кроме особых случаев, вроде считывания файлов в память в цикле.
не хочу спорить, но по опыту это не всегда так или несовсем так, часто замечал что память течет там где уже не должна(на сервере из задач только агент менеджер)

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

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

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

Yakov
Подскажи, пожалуйста, которая из Lsi_info возвращает объем использованной памяти?
 
Подскажи, пожалуйста, которая из Lsi_info возвращает объем использованной памяти?
Забанили в гугле? Тогда мы идем к Вам :-)

Первая ссылка:
lsi_info(50) = LS memory allocated
lsi_info(51) = LS memory allocated from OS
lsi_info(52) = LS blocks used
 
lsi_info(50) = LS memory allocated
lsi_info(51) = LS memory allocated from OS
lsi_info(52) = LS blocks used
Да, уже заюзал. Только возник вопрос - какая разница между LS memory allocated, LS memory allocated from OS и LS blocks used?
 
По-моему, LS memory allocated from OS - память, которую Lotus "взял" у ОС (столбец "Память" в Task Manager'е), LS memory allocated - память, которую Lotus уже использует, LS blocks used - количество блоков использованной памяти (Lotus выделяет и освобождает память блоками размером (LS memory allocated) / (LS blocks used)).
 
Yakov
Теже .... только в профиль...
Мне нужно корректно измерить сколько памяти сожрал агент (можно в относительных еденицах). Которую функцию мне использовать?

Потестировал очищение памяти, у меня получилось что:
1. Метод delete в классе можно не определять
2. Достаточно делать все delete (не забывать делать delete в цикле)
3. Использование delete замедляет исполнение агента на 10-20%
 
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]
 
Я бы попробовал измерить и сравнить 4 величины: использование памяти (lsi_info(50)) до запуска агента (в коде, запускающем агент), в начале работы агента (в коде агента), в конце работы агента (в коде агента), после завершения работы агента (в коде, запускающем агент после Delete agent).
 
nvy
Ясень пень так. Просто иногда нужно внутри цикла инициировать объект

Yakov
Сегодня днем поищу в инете инфу по этому поводу
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!