Сборка мусора в Lotus

02.04.2005
170
1
#1
Проблема агентов в Лотусе только одна - нужно писать правильный код и правильно чистить за собой мусор. Если этого не делать, то таки да, будут проблемы с подвисанием сервера. Но если сделать все правильно то проблем не будет.

Вот нашел, уже писал когда-то пример на этом форуме:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'>import lotus.domino.*;

public class Temp extends AgentBase {

//Хорошая реализация
public void V1() {
ViewEntry entry = null;
ViewEntryCollection col = null;
Document doc = null;
View view = null;

try {
col = view.getAllEntries();
int appCount = col.getCount();
for (int i = 1; (i <= appCount); i++) {
entry = col.getNthEntry(i);
doc = entry.getDocument();
// ....
doc.recycle();
entry.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}

// Плохая реаллизация. Утечка памяти
public void V2() {
Document doc = null;
View view = null;
try {
doc = view.getFirstDocument();
while (doc != null) {
// ...
doc = view.getNextDocument(doc);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}[/CODE]
 

RixPvl

Well-known member
30.11.2011
85
0
#2
Извиняюсь за возможно глупый вопрос, а чем это может помочь? Просто я яву начал только учить и возможно много еще не знаю. :)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#3
нотусёвые объекты достаточно объемны, и сборка мусора вызывается несколько отличным образом от "обычной" jvm
выше упоминали - размер кучи (да и стека) jvm ограничены (дефолтно - "небольшим" значением), в LS они ограничены только размером свободной памяти процесса (до 2Гб)
 

Кирилл Шваб

Well-known member
30.06.2006
145
4
#4
В Java с памятью надо быть аккуратнее, т.к. каждый раз когда выполняется doc = view.getNextDocument(doc), то создается новая переменная, под которую выделяется память.
Т.е. если в представлении будет 1000 документов, то к концу цикла у тебя будет выделено памяти под 1000 переменных типа Document.
Поэтому перед очередным присвоением необходимо освобождать память, которую занимает переменная.

Посмотри в хелпе описание метода getNextDocument - там сказано про освобождение памяти.
 

RixPvl

Well-known member
30.11.2011
85
0
#5
Подскажите все ли правильно сделал (по очищению объектов)? вроде как все сделал а памяти отъедает как не знаю кто, за каждый запуск по 5-10% и причем после завершения агенте память не возращается, видно все еще висит в памяти, как решить и что делать уже и не знаю...
 

RixPvl

Well-known member
30.11.2011
85
0
#6
Тут почитал не знаю правильно ли понял людей, но есть функция System.gc() которая запускает очистку кучи, стоит ли использовать?
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#7
Говорили же, что надо recycle. Везде используется = null, а оно как мёртвому припарка.

Я в секции finally{ ... } чищу все поля-объекты класса и некоторые объекты в агентах, - особенно SWT-объекты на локале, т.к. не почистишь, в следующий раз агент не запустится.
И в каждом методе стараюсь смотреть, если объект при выходе из метода не будет использоваться, то стараюсь его грохать (метод recycle + null, если recycle не поддерживается, то просто = null).
Всё это делаю в основном для объектов собственных классов, для всех Lotus-объектов, поддерживающих recycle и для Java-объектов, содержащих большие объёмы данных, как то коллекции, векторы и т.п.
Не знаю, может ещё кто-нибудь что-то подскажет.
 

RixPvl

Well-known member
30.11.2011
85
0
#8
Код:
					ntTmp = doc;
doc = null; <--- если тут делать recycle, то цикл завершается и дальше не идет, причем ошибок ни каких нет
doc = view.getNextDocument(ntTmp);
ntTmp.recycle();
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#9
Надо делать как в хэлпе написано:
RixPvl сказал(а):
+ сделал изменение при переборе клекции по аналогии из хелп лотуса
Код:
	 while (doc != null) {
System.out.println
("\t" + doc.getItemValueString("Subject"));
tmpdoc = view.getNextDocument(doc);
doc.recycle();
doc = tmpdoc;
}
У меня работает.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#10
принудительный вызов gc никчему адекватному не приведёт :rolleyes:
при это не надо забывать, что ИБМ по-своему реализует gc
освобождение (recycle) нотусёвых объектов крайне желательно, ибо... они (объекты) связаны с нативным кодом, а "такие" объекты могут не освобождаться при сборке
 

RixPvl

Well-known member
30.11.2011
85
0
#12
Код:
	 while (doc != null) {
System.out.println
("\t" + doc.getItemValueString("Subject"));
tmpdoc = view.getNextDocument(doc);
doc.recycle();
doc = tmpdoc;
}
а tmpdoc убивать ненадо?
 

nvyush

Lotus team
22.04.2009
2 317
0
#13
а tmpdoc убивать ненадо?
Не путайте объект и указатель на объект
<!--shcode--><pre><code class='java'> tmpdoc = view.getNextDocument(doc); //создаём объект для следующего документа и присваиваем его адрес указателю tmpdoc
doc.recycle(); //утилизируем объект документа, на который указывает doc
doc = tmpdoc; //присваиваем указателю doc адрес, на который указывает tmpdoc
// tmpdoc.recycle(); //этим действием будет уничтожен объект, на который указывают и tmpdoc и doc[/CODE]
 

Kee_Keekkenen

Well-known member
05.09.2006
639
4
#14
если что-то хочешь найти про очистку, то именно выше описанное во всех статьях и пишут..

а вообще очистка (вплоть до итемов) очень помогает джаве не падать..

как вы думаете, что будет если сделать так:
<!--shcode--><pre><code class='java'>doc.replaceItemValue( "test", "1" ).recycle();
doc.getItemValueString( "test" );[/CODE]а самое главное почему ?! с документом иначе получается..
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#15
как вы думаете, что будет если сделать так:

doc.replaceItemValue( "test", "1" ).recycle();
doc.getItemValueString( "test" );

а самое главное почему ?! с документом иначе получается..
Не пробовал, но думаю, что:
- после первой строки ничего особенного не произойдёт, т.к. replaceItemValue возвращает объект, аналогичный NotesItem'у, по значению, который поддерживает recycle;
- 2-я строка также прекрасно отработает, т.к. она не работает с тем Item-объектом, который был возвращён и ЗАrecycleН, т.е. берётся из дока заново.

Это то же самое, что в LS получить объект NotesItem, сделать ему Delete, а потом выполнить getItemValue.
 

Kee_Keekkenen

Well-known member
05.09.2006
639
4
#16
принудительный вызов gc никчему адекватному не приведёт wink.gif

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

не так давно написали красивый конвейер для выполнения обработки данных, который реализовал выполнение всего трех схем (с контролем эксцепшионов и рестартом с места падения, отчетностью по выполнению), в каждой из которых было по 5-7 действий.. в результате, даже при тотальной чистке объектов все равно не хватало памятульки и где-нибудь вылетало, при чем вылеты были двух типов:
1. после makeresponce копировалось поле $REF, так оно не копировалось, хотя было в докумиенте - это отлавливаемый эксцепцион (ругалось на то, что объект был удален или рециклен)
2. где-то произвольно код вылетает и никаких эксцепшионов нет - просто остановка выполнения кода

так вот, после того, как каждое действие (вызов выполнения) было вынесено в отдельный агент, и после каждого запуска агента-действия, вызывается агент с gc, все стало просто зело предивно работать..
 

Kee_Keekkenen

Well-known member
05.09.2006
639
4
#17
Не пробовал, но думаю, что:
- после первой строки ничего особенного не произойдёт, т.к. replaceItemValue возвращает объект, аналогичный NotesItem'у, по значению, который поддерживает recycle;
- 2-я строка также прекрасно отработает, т.к. она не работает с тем Item-объектом, который был возвращён и ЗАrecycleН, т.е. берётся из дока заново.

Это то же самое, что в LS получить объект NotesItem, сделать ему Delete, а потом выполнить getItemValue.
:D я тоже так думал, однако java-парадигма ломает документ идею лотуса :)
итем это джава объект, если ему сделать рецикл, то ниточка покоторой можно получить поле из документа изчезнет - ништяк (в плохом смысле)..
технически выглядит как-будто было сделано removeItem.. поле будет доступно, только поле переполучения документа, если, конечно, было сохранение, правда клево ?!..

Добавлено: тут не ясно что имеется в виду, т.к. неизвесно как там в этой доминге все устроено в плане утилизации..
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#18
Kee_Keekkenen
"Ну... значит моя версия была ошибочной" © :)