Почему работает временная переменная для утилизации java-объекта в XPages?

1

Есть много сообщений о том, почему нам нужно перерабатывать объекты в Java.

То, что я не понимаю из приведенного ниже примера IBM, заключается в том, что переработка переменной "doc" считается полезной, но переменной "temp" нет.

Я полностью понимаю, что если вы переработаете переменную владельца места, вам понадобится "временная" переменная для getnextdocument() для работы, но почему бы просто не иметь одну переменную и не перерабатывать эту переменную после цикла

Почему стоимость не рециркуляции "Темп" приемлема там, где стоимость не рециркуляции "док" является неприемлемой.

http://www-01.ibm.com/support/docview.wss?uid=swg21097861

import lotus.domino.*; 
public class JavaAgent extends AgentBase { 
public void NotesMain() {
try { 
Session session = getSession(); 
AgentContext agentContext = session.getAgentContext(); 
Database db = agentContext.getCurrentDatabase(); 
View v = db.getView("SomeView");
// turn off auto-update so that if we make a change to a document // and resave, it won't affect the sort order in the view 
v.setAutoUpdate(false); 

Document doc = v.getFirstDocument(); 
Document temp = null;   
//sets the temp for garbage collection immediately 
while (doc != null) 
{ 
// do something with the document here... 
// whatever, just don't delete it (yet)! 
temp = v.getNextDocument(doc);   // get the next one 
doc.recycle();  // recycle the one we're done with 
doc = temp; 
} 
// end while 

} catch(Exception e)
{ 
e.printStackTrace(); 
}
}
}
  • 0
    Спасибо ВСЕМ, кто нашел время, чтобы прокомментировать. Я думаю, что все ответы верны, но Павел сделал все возможное (как он часто делает).
Теги:
xpages

4 ответа

10
Лучший ответ

Ключ понимает, что такое утилизация. Recycle ничего не делает для переменной (например, doc, tmp). Recycle очищает дескриптор до объекта C++, соответствующего документу, базе данных, что угодно. Поэтому рассмотрим следующий код:

Document tmp = dc.getNextDocument(doc);
doc.recycle();
doc = tmp;

Вы перерабатываете дескриптор объекта C++, который вы только что повторили. Теперь рассмотрим:

Document tmp = dc.getNextDocument(doc);
doc = tmp;
tmp.recycle();

Вы не перерабатываете tmp. Вы перерабатываете дескриптор документа, который вы назначили tmp. Этот дескриптор также присваивается переменной doc. Поэтому, когда вы пытаетесь вызвать doc.getFirstItem("myField"), вы получаете сообщение об ошибке, что объект был переработан или удален. Потому что, перерабатывая tmp, вы также переработали doc, потому что вы перерабатываете дескриптор в основной объект C++. У вас также больше нет переменной Java, связанной с ранее итерационным документом. Таким образом, у вас нет возможности перерабатывать этот объект.

Также, почему tmp или doc не нуждаются в повторной утилизации после цикла. Последняя итерация пытается получить следующий Документ после последнего в коллекции. Это значение равно null, поэтому никакой дескриптор объекта C++ не был получен. Поэтому, поскольку никакой дескриптор не был извлечен, нечего перерабатывать.

Это также объясняет, почему вам действительно нужно перерабатывать в цикле. В 8.5.0 количество ручек, к которым я обращался, перед сбоем сервера составляло около 20 000. Это было увеличено в 9,0. Игнорируйте циклы, и количество дескрипторов, которые большинство кодов на XPage будут открыты в любое время, будет меньше 100. Поэтому зачем тратить время на повторное использование ваших усилий, когда вы никогда не столкнетесь с сервером, если вы этого не сделаете? Поскольку в конце запроса Session будет переработана вместе со всеми ее потомками, так что любой C++ обрабатывает вас, скорее всего, будет доступен.

Но вам может потребоваться переработать больше, чем просто объекты Document или ViewEntry в циклах. Любой вызов getColumnValues() для представления, содержащего даты, создаст объект DateTime, даже если вы не используете этот столбец в коде. Этот DateTime является дочерним элементом Session, а не ViewEntry. Поэтому вам нужно вызвать .recycle(colVals), передавая в Vector, который содержит значения столбца, любому объекту Domino, который еще не был переработан. Любое Name или объект DateTime созданный в цикле, также нуждаются в переработке.

Java-память регулярно собирает мусор, поэтому не нужно устанавливать переменные в нуль.

См. Комментарий Натана в моем сообщении в блоге с декабря 2009 года, когда я впервые ударил его SSJS http://www.intec.co.uk/go-green-and-recycle-the-important-information-any-non-java-xpages -dev-needs-to-know/ и мое сообщение в блоге о рисках getColumnValues () http://www.intec.co.uk/the-perils-of-getcolumnvalues-get0/

4

Каждый документ имеет свою собственную ручку.

Если вы напишете doc = v.getNextDocument(doc); у вас не будет возможности переработать "старый" документ. Если вы сделаете это до строки, то getNextDocument() завершится неудачно, потому что параметр doc уже ушел, а послесловия вы не можете его переработать, потому что переменная doc указывает на новый документ.

Итак, фокус в том, чтобы сохранить "старый" документ в переменной doc, поставить следующий документ в переменную temp, recycle doc и назначить temp для doc.

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

Пока блок будет завершен, когда следующий документ будет равен нулю. В конце while-block temp и doc будет null и больше не будут указывать на документ и почему temp или doc не нужно перерабатывать после while-block.

1

представьте, что у нас есть вид с двумя документами

в первый раз, когда вы переходите к циклу, у вас есть переменная java doc "указывая" на c++ дескриптор документа заметок A. в конце первого прогона цикла вы имеете переменные java temp и doc, указывающие на c++ дескриптор документа B при достижении последнего документа строка "temp = v.getNextDocument(doc);" вернет null, дескриптор документа B будет выпущен и вуаля :-)

0

Из того, что я понимаю (мои знания/терминология здесь немного туманны, и я сир, кто-то соберет правильные термины), потому что каждый раз, когда вы создаете новый объект Document, даже если вы назначаете одну и ту же переменную Java, базовые [ CN10] на самом деле создает новый указатель (вместо повторного использования старого).

Это означает, что вы попали в утечку памяти.

Метод recycle указывает, что код C++ освобождает указатель, поэтому вам нужно сделать это внутри цикла.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню