有很多关于我们为什么需要在Java中回收对象的帖子.
我从下面的IBM示例中无法理解的是,为什么回收"doc"变量被认为是有用的,但"temp"变量不是.
我完全理解,如果你重新设置占位符变量,那么你需要一个"临时"变量来使getnextdocument()工作,但为什么不只是有一个变量并在循环后循环该变量
为什么不回收"温度"的成本是可以接受的,因为不回收"doc"的成本是不可接受的.
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();
}
}
}Run Code Online (Sandbox Code Playgroud)
Pau*_*ers 10
关键是了解回收的作用.Recycle对变量没有任何作用(例如doc,tmp).Recycle清除对应于文档,数据库等的C++对象的句柄.请考虑以下代码:
Document tmp = dc.getNextDocument(doc);
doc.recycle();
doc = tmp;
Run Code Online (Sandbox Code Playgroud)
您正在将句柄回收到您刚刚迭代的C++对象.现在考虑:
Document tmp = dc.getNextDocument(doc);
doc = tmp;
tmp.recycle();
Run Code Online (Sandbox Code Playgroud)
你没有回收tmp.您正在将句柄回收到您指定的文档tmp.该句柄也分配给doc变量.因此,当您尝试调用时doc.getFirstItem("myField"),您会收到对象已被回收或删除的错误.因为通过回收tmp,你还回收了doc,因为你正在回收底层C++对象的句柄.您也不再拥有与先前迭代的Document相关的Java变量.所以你无法回收那个对象.
这也是循环后为什么tmp或doc不需要回收的原因.最后一次迭代尝试在集合中的最后一个文档之后获取下一个Document.这是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内存经常被垃圾收集,因此不需要将变量设置为null.
从2009年12月我第一次点击SSJS http://www.intec.co.uk/go-green-and-recycle-the-important-information-any-non-java-xpages看看Nathan对我博客文章的评论-dev-needs-to-know和我关于getColumnValues()的风险的博客文章http://www.intec.co.uk/the-perils-of-getcolumnvalues-get0/
| 归档时间: |
|
| 查看次数: |
760 次 |
| 最近记录: |