最佳实践是在创建 Domino 对象的范围内回收所有对象。然而,回收任何对象会自动回收它“下面”的所有对象。因此,在您的示例方法中,您can't回收 wDb,因为这会导致 wDoc 也被回收,所以您将返回回收的文档句柄。
因此,如果您想确保不泄漏内存,最好以相反的顺序回收对象(例如,首先是文档,然后是视图,然后是数据库)。这往往需要构建您的方法,以便您可以使用 Domino 对象执行您需要的任何操作inside无论什么方法获取它的句柄。
例如,我假设您定义一个获取配置文档的方法的原因是为了您可以从中提取配置设置的值。因此,与其定义一个返回文档的方法,也许定义一个返回文档的方法会更好。物品价值:
private Object lookupItemValue(String configKey, itemName) {
Object result = null;
Database wDb = null;
View wView = null;
Document wDoc = null;
try {
Session sess = ExtLibUtil.getCurrentSession();
wDb = sess.getDatabase(sess.getServerName(), this.dbname1);
wView = wDb.getView(this.viewname1);
wDoc = wView.getDocumentByKey(configKey, true);
this.debug("Got a doc for key: [" + configKey + "]");
result = wDoc.getItemValue(itemName);
} catch (NotesException ne) {
if (this.DispLookupErrors)
ne.printStackTrace();
this.lastErrorMsg = ne.text;
this.debug(this.lastErrorMsg, "error");
} finally {
incinerate(wDoc, wView, wDb);
}
return result;
}
上述内容有几点值得解释一下:
- 通常在Java中,我们在第一次使用时声明变量,而不是目录样式。但对于 Domino 对象,最好恢复到 TOC,这样,无论是否抛出异常,我们都可以在完成后尝试回收它们……因此使用了finally。
- 返回对象(应该是一个项目值,而不是文档本身)也在目录中声明,因此我们可以在方法末尾返回该对象 - 再次,无论是否遇到异常(如果存在异常)例外,大概它仍然是空的)。
- 此示例调用一个实用程序方法,该方法允许我们将所有 Domino 对象传递给单个方法调用以进行回收。
这是该实用方法的代码:
private void incinerate(Object... dominoObjects) {
for (Object dominoObject : dominoObjects) {
if (null != dominoObject) {
if (dominoObject instanceof Base) {
try {
((Base)dominoObject).recycle();
} catch (NotesException recycleSucks) {
// optionally log exception
}
}
}
}
}
它是私有的,因为我假设您只是在同一个 bean 中定义它,但最近我倾向于将其定义为 Util 类的公共静态方法,允许我从几乎任何地方遵循相同的模式。
最后一点:如果您要从配置文档中检索大量项目值,显然为您想要返回的每个项目值建立一个新的数据库、视图和文档句柄将是昂贵的。因此,我建议重写此方法以接受项目名称的 List (或 String[ ])并返回结果值的 Map 。这样,您可以为数据库、视图和文档建立单个句柄,检索所需的所有值,然后在实际使用返回的项值之前回收 Domino 对象。