Java. Ldap.

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#1
Коллеги, никто не сталкивался с такой ошибкой?

Agent Manager: Agent  error: Error cleaning up agent threads
Agent Manager: Agent  error: java.lang.IllegalThreadStateException
Agent Manager: Agent  error:  at java.lang.ThreadGroup.destroy(ThreadGroup.java:726)
Agent Manager: Agent  error:  at java.lang.ThreadGroup.destroy(ThreadGroup.java:744)
AM  Agent Manager: Agent  error:  at lotus.domino.AgentLoader.runAgent(Unknown Source)

Ошибка возникает уже после того, как отработал последний оператор. Объекты все закрываются.

Да. Кстати, все работало нормально, пока лотусня 6.5 стояла. После миграции на 7 появились эти утечки памяти ;) Прообгейдилась java до 1.4.2, может с этим как-то связано...
 

morpheus

скриптописец
07.08.2006
3 915
1
#2
предположение. переподписанные ява аплеты скачали установили?
 

vincent_vega

Well-Known Member
Lotus team
02.04.2005
168
1
#4
То что лотус не умеет хорошо за собой память чистить к сожалению факт:) Могу посоветовать побольше памяти под джаву выделить и по возможности проапгрейдить сервер до самой последней версии.
http://www.ibm.com/developerworks/lotus/li...bles/index.html
Периодически перезагружать сервер. И самое главное - нужно пересмотреть и оптимизировать код. Особенно при работе с коллекциями документов
Обновления аплетов вам не помогут, если это не свзяано с самтаймом (что то мне подсказывает что это так)
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#5
То что лотус не умеет хорошо за собой память чистить к сожалению факт:) Могу посоветовать побольше памяти под джаву выделить и по возможности проапгрейдить сервер до самой последней версии.
http://www.ibm.com/developerworks/lotus/li...bles/index.html
Периодически перезагружать сервер. И самое главное - нужно пересмотреть и оптимизировать код. Особенно при работе с коллекциями документов
Обновления аплетов вам не помогут, если это не свзяано с самтаймом (что то мне подсказывает что это так)
Спасибо, но мне кажется увеличение кол-ва памяти не спасает от утечек памяти. А перегружать почаще сервер не получится, ибо он стоит у заказчика и на нем в течении дня работает очень большое кол-во пользователей.
По поводу пересмотра кода, вряд ли, ибо он уже оптимизирован как надо, да и как было сказано выше, на 6.5 все работало нормально.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#6
вот хорошо бы знать что за код юзается...
потому как доминошная жвм очень не любит сторонних нитей и асинхронных объектов (типа открытых потоков, сокетов...)
в агенте все обекты должны мочь уничтожаться, по завершении агента
ежели это невозможно по архитектуре приложения - выносить библиотеку из базы (покладевать в jvm/ext или пропис. путя в нотес ини)
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#7
вот хорошо бы знать что за код юзается...
потому как доминошная жвм очень не любит сторонних нитей и асинхронных объектов (типа открытых потоков, сокетов...)
в агенте все обекты должны мочь уничтожаться, по завершении агента
ежели это невозможно по архитектуре приложения - выносить библиотеку из базы (покладевать в jvm/ext или пропис. путя в нотес ини)
Весь агент выложить не могу, но ассинхронных объектов вроде нет.
Все объекты закрываются:
Код:
finally {
try {
System.out.println("Recycling Domino objects...");
if (pfdoc!=null) pfdoc.recycle();
if (staffProfileDoc!=null) staffProfileDoc.recycle();
if (mailDoc!=null) mailDoc.recycle();
if (deptDoc!=null) deptDoc.recycle();
if (docCol!=null) docCol.recycle();
if (viewUniqueTest!=null) viewUniqueTest.recycle();
if (viewRetired!=null) viewRetired.recycle();
if (missingPeopleView!=null) missingPeopleView.recycle();
if (viewStaffSearchRu!=null) viewStaffSearchRu.recycle();
if (viewStaffSearchPersopPosts!=null) viewStaffSearchPersopPosts.recycle();
if (viewStaffSearchHN!=null) viewStaffSearchHN.recycle();
if (viewStaffSearchEN!=null) viewStaffSearchEN.recycle();
if (viewDepts!=null) viewDepts.recycle();
if (missingPeopleView!=null) missingPeopleView.recycle();
if (dbCurr!=null) dbCurr.recycle();
if (dbStaff!=null) dbStaff.recycle();
if (moveAgt!=null) moveAgt.recycle();
if (srvName!=null) srvName.recycle();
if (rtstyle!=null) rtstyle.recycle();
if (rtstyleBold!=null) rtstyleBold.recycle();
if (agentContext!=null) agentContext.recycle();
ctx.close();
ctx=null;
session.recycle();
//System.gc();
System.out.println("Domino objects have been recycled!");
}
 

vincent_vega

Well-Known Member
Lotus team
02.04.2005
168
1
#8
Памяти все таки лучше добавить, а сервер можно перегружать раз в месяц ночью (настроить по расписанию) это не большая проблема как по мне, но стабильности добавит.

То что в файнали ресайклится это хорошо:) но в примере я заметил docCol, view* - если в коллекции или представлении идет перебор документов, то здесь и есть как раз потенциальное место утечки памяти.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#9
вот это if (agentContext!=null) agentContext.recycle();
зачем?
Нотуса сама это делает
все объекты уничтожатся после завершения, не надо в файнали это делать
их надо после использования уничтожать, сразу
ctx остался - ежели внешняя шняга - наружи д.б. и желательно не закрывать её до завершения жвм
сделать сиглтоном (в наружней библе)
потому как ежели оно вызывает нативные длл - могет жрать память при многократных передергиваниях
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#10
Памяти все таки лучше добавить, а сервер можно перегружать раз в месяц ночью (настроить по расписанию) это не большая проблема как по мне, но стабильности добавит.

То что в файнали ресайклится это хорошо:) но в примере я заметил docCol, view* - если в коллекции или представлении идет перебор документов, то здесь и есть как раз потенциальное место утечки памяти.
Добавлять пробовали, не помогает.

Да, перебор документов есть. А в чем проблематичность перебора?

вот это if (agentContext!=null) agentContext.recycle();
зачем?
Нотуса сама это делает
все объекты уничтожатся после завершения, не надо в файнали это делать
их надо после использования уничтожать, сразу
ctx остался - ежели внешняя шняга - наружи д.б. и желательно не закрывать её до завершения жвм
сделать сиглтоном (в наружней библе)
потому как ежели оно вызывает нативные длл - могет жрать память при многократных передергиваниях
Закрываю на всякий случай.. уже не знали что проверить, поэтому на всякий добавили... хуже точно не будет.

ctx, да остался, до завершения жвм

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

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#11
я к тому что ежели библа в базе - то объект ctx будет уничтожаться (попытка) и ваш клозе не изменит ситуации!
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#12
я к тому что ежели библа в базе - то объект ctx будет уничтожаться (попытка) и ваш клозе не изменит ситуации!
Да, библа в базе, конечно. Хуже от клосе не будет :)

В общем написали PMR в IBM, подождем, что они ответят...
 

vincent_vega

Well-Known Member
Lotus team
02.04.2005
168
1
#13
Да, перебор документов есть. А в чем проблематичность перебора?
ну приблизительно вот так

Код:
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();
}
}

}
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#14
По-моему так уже кто-то пробовал, судя по закоментированным строчкам :) :)

Код:
		deptDoc = viewDepts.getFirstDocument();
while (deptDoc != null) {

бла-бла...

//deptDoc.recycle();
//deptDoc=null;
deptDoc=viewDepts.getNextDocument (deptDoc);
}
 
Y

Yakov

Гость
#15
abbatik, я бы еще каждый вызов recycle() в try...catch обернул:
Код:
try { if (pfdoc!=null) pfdoc.recycle(); } catch (NotesException ex) {}

Надо так:
Код:
		deptDoc = viewDepts.getFirstDocument();
while (deptDoc != null) {

бла-бла...

Document tmpDoc = viewDepts.getNextDocument (deptDoc);
deptDoc.recycle();
deptDoc = tmpDoc;
}
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#16
уже не раз говорено - ежели била неизвестно шо делает - луча её наружу вынести
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#17
Переписал я с нуля эту функцию.. ошибка осталась.

Методом сокращения области, при появлении ошибки, обнаружил, что она появляется, когда раскоменчиваешь кусок:
Код:
while ( list.hasMoreElements() ) {
res=null;
res = (SearchResult)list.next();

бла-бла...
}
При этом в начале функции переменные объявляются:
Код:
SearchResult res = null;
NamingEnumeration list = null;
А в конце закрываются:
Код:
list.close();
list=null;
res=null;
Может кто сталкивался? Обойти не получается, ибо данные из LDAP по другому не достать :(
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#18
такими кусками ничего непонятно...
причины неожиданного поведения жвм:
-очистка объекта во время обращения к нему (кривость кода)
-попытка закрытие сокетов, а они не могут (не хотят)
-криво реализованная мульти-нитевость
-меморилики в нативных библах
 

abbatik

Well-Known Member
Lotus team
20.10.2008
277
0
#19
такими кусками ничего непонятно...
причины неожиданного поведения жвм:
-очистка объекта во время обращения к нему (кривость кода)
-попытка закрытие сокетов, а они не могут (не хотят)
-криво реализованная мульти-нитевость
-меморилики в нативных библах
Я выложил этот кусок, потому что именно его присутствие приводит к ошибке.

1. Не похоже, т.к. весь код отрабатывает правильно. Ошибка выскакивает уже после последней строчки финалайза NotesMain, т.е. при терминэйте.
2. Опять же нет, ибо на момент выскакивания ощибки все сокеты обнулены.
3. Сложный вопрос. Код не особо сложный, поэтому тоже не похоже.. Хотя возможно какие-то классы, что-то пораждают.
4. От библиотек отказался и сократил функцию до 5ти функций.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#20
1 - ежели мультинитевое - как раз возможно такое
2 - а как это проверить, разница м.б. на уровне 1 мс (опятьже ежели код не thread safe)
3 - вот то-то и оно
4 - тока нативная джава и только ваш код?