为什么使用临时变量在XPages中回收Java对象有效? - java

关于为什么我们需要回收Java中的对象的文章很多。

我从下面的IBM示例中无法理解的是为什么回收“ doc”变量被认为有用,而“ temp”变量却没有用。

我完全理解,如果您回收占位符变量,则需要一个“临时”变量来使getnextdocument()工作,但为什么不只有一个变量并在循环后回收该变量

为什么不回收“ doc”的成本无法承受,为什么不回收“ Temp”的成本是可以接受的。

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(); 
}
}
}

参考方案

关键是要了解回收的作用。 Recycle对变量(例如doc,tmp)不起作用。回收清除与文档,数据库等对应的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变量。因此,您无法回收该对象。

这也是tmpdoc在循环后不需要回收的原因。最后的迭代尝试获取集合中最后一个文档之后的下一个Document。这是空的,因此未检索到C ++对象的句柄。因此,由于未检索到任何句柄,因此没有可回收的东西。

这也是为什么您只需要循环循环的原因。在8.5.0中,在使服务器崩溃之前我访问的句柄数量约为20,000。在9.0中已增加。忽略循环,并且XPage上大多数代码在任何一次都可以打开的句柄数量少于100。那么,如果不这样做,为什么不浪费服务器资源又为什么要浪费精力呢?因为在请求结束时,Session及其所有后代将被回收-因此您可能已访问任何C ++句柄。

但是您可能需要循环循环使用多个对象,而不仅仅是DocumentViewEntry。即使未在代码中使用该列,对包含日期的视图的任何getColumnValues()调用都将创建一个DateTime对象。该DateTimeSession的子级,而不是正在迭代的ViewEntry。因此,您需要调用.recycle(colVals),将包含列值的Vector传递给尚未回收的任何Domino对象。在循环中创建的任何NameDateTime对象也需要回收。

Java内存会定期进行垃圾回收,因此无需将变量设置为null。

请参阅Nathan在2009年12月第一次用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/危险所发表的博客文章的评论。

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

Java:从类中查找项目名称 - java

仅通过类的实例,如何使用Java反射或类似方法查找项目名称?如果不是,项目名称(我真正想要的是)可以找到程序包名称吗? 参考方案 项目只是IDE使用的简单组织工具,因此项目名称不是类或JVM中包含的信息。要获取软件包,请使用Class#getPackage()。然后,可以调用Package#getName()将包作为您在代码的包声明中看到的String来获取…