问题描述
我使用一个函数来访问配置文件:
I use a function to get access to a configuration document:
private Document lookupDoc(String key1) {
try {
Session sess = ExtLibUtil.getCurrentSession();
Database wDb = sess.getDatabase(sess.getServerName(), this.dbname1);
View wView = wDb.getView(this.viewname1);
Document wDoc = wView.getDocumentByKey(key1, true);
this.debug("Got a doc for key: [" + key1 + "]");
return wDoc;
} catch (NotesException ne) {
if (this.DispLookupErrors)
ne.printStackTrace();
this.lastErrorMsg = ne.text;
this.debug(this.lastErrorMsg, "error");
}
return null;
}
在另一种方法中,我使用这个函数来获取文档:
In another method I use this function to get the document:
Document wDoc = this.lookupDoc(key1);
if (wdoc != null) {
// do things with the document
wdoc.recycle();
}
在回收 Document 对象时是否应该回收 Database 和 View 对象?还是应该在函数返回 Document 之前回收那些?
Should I be recycling the Database and View objects when I recycle the Document object? Or should those be recycled before the function returns the Document?
推荐答案
最佳实践是在创建 Domino 对象的范围内回收所有 Domino 对象.但是,回收任何对象会自动回收它下面"的所有对象.因此,在您的示例方法中,您不能回收 wDb,因为这也会导致 wDoc 也被回收,因此您将返回一个回收的 Document 句柄.
The best practice is to recycle all Domino objects during the scope within which they are created. However, recycling any object automatically recycles all objects "beneath" it. Hence, in your example method, you can't recycle wDb, because that would cause wDoc to be recycled as well, so you'd be returning a recycled Document handle.
因此,如果您想确保不泄漏内存,最好以相反的顺序回收对象(例如,首先是文档,然后是查看,然后是数据库).这往往需要构建您的方法,以便您可以做任何需要/使用 Domino 对象inside 的任何方法获取它的句柄.
So if you want to make sure that you're not leaking memory, it's best to recycle objects in reverse order (e.g., document first, then view, then database). This tends to require structuring your methods such that you do whatever you need to/with a Domino object inside whatever method obtains the handle on it.
例如,我假设您定义获取配置文档的方法的原因是您可以从中提取配置设置的值.因此,与其使用返回文档的方法,不如定义一个返回项目值的方法:
For instance, I'm assuming the reason you defined a method to get a configuration document is so that you can pull the value of configuration settings from it. So, instead of a method to return the document, perhaps it would be better to define a method to return an item value:
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;
}
关于上述内容,有几点值得解释:
There are a few things about the above that merit an explanation:
- 通常在 Java 中,我们在第一次使用时声明变量,而不是目录样式.但是对于 Domino 对象,最好恢复到 TOC,这样,无论是否抛出异常,我们都可以在完成后尝试回收它们......因此使用 finally.
- 返回对象(应该是项目值,而不是文档本身)也在 TOC 中声明,因此我们可以在方法结束时返回该对象 - 同样,无论是否遇到异常(如果有一个例外,大概它仍然是空的).
- 此示例调用了一个实用程序方法,该方法允许我们将所有 Domino 对象传递给单个方法调用以进行回收.
这是该实用程序方法的代码:
Here's the code of that utility method:
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 类的公共静态方法,允许我从几乎任何地方遵循相同的模式.
It's private, as I'm assuming you'll just define it in the same bean, but lately I tend to define this as a public static method of a Util class, allowing me to follow this same pattern from pretty much anywhere.
最后一点:如果您要从配置文档中检索大量项目值,显然为要返回的每个项目值建立一个新的数据库、视图和文档句柄会很昂贵.所以我建议重写这个方法来接受 List(或 String[]) 项名称并返回 Map.的结果值.这样您就可以为数据库、视图和文档建立一个单一的句柄,检索您需要的所有值,然后在实际使用返回的项目值之前回收 Domino 对象.
One final note: if you'll be retrieving numerous item values from a config document, obviously it would be expensive to establish a new database, view, and document handle for every item value you want to return. So I'd recommend overriding this method to accept a List<String> (or String[ ]) of item names and return a Map<String, Object> of the resulting values. That way you can establish a single handle for the database, view, and document, retrieve all the values you need, then recycle the Domino objects before actually making use of the item values returned.
这篇关于在 Java Beans 中回收 Domino 对象的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!