0

我有一个会话范围的 bean,它读取视图的内容并存储 SelectItem 对象的哈希图。这些然后用于填充 XPage 上的组合框值。

代码工作正常,除非我尝试在最内层循环中回收 ViewEntry 对象。如果该行被注释掉,我的 SelectItems 会很好地返回。如果该行未注释,则我的组合框为空。所以我想知道的是:

  1. 为什么会这样?
  2. 我该如何解决这个问题并像优秀的开发人员一样正确回收对象?
  3. 如果我不能明确回收对象,对内存等有什么潜在影响?

代码(突出显示问题行并当前已注释掉):

public class comboBox extends HashMap<String, List<SelectItem>> implements Serializable {
    private static final long serialVersionUID = 1L;
    public comboBox() {
        this.init();
    }

    private void init() {
        Database database = null;
        View vwData = null;
        ViewNavigator navData = null;
        try {
            PrimeUser thisUser = (PrimeUser) resolveVariable(FacesContext.getCurrentInstance(), "PrimeUser");
            String lang = thisUser.getLang();
            database = getCurrentDatabase();
            vwData = database.getView("DataLookup");
            navData = vwData.createViewNavFromCategory(lang);
            ViewEntry keyCat = navData.getFirst();
            ViewEntry nextCat = null;
            while (keyCat != null) {
                String thisKey = (String) keyCat.getColumnValues().get(1);
                List<SelectItem> options = new ArrayList<SelectItem>();
                options.add(new SelectItem("Please select..."));
                ViewEntry dataEntry = navData.getChild(keyCat);
                ViewEntry nextChild = null;
                while (dataEntry != null) {
                    nextChild = navData.getNextSibling();
                    Object optValue = dataEntry.getColumnValues().get(2);
                    String optLabel = (String) dataEntry.getColumnValues().get(3);
                    options.add(new SelectItem(optValue, optLabel));

                    // dataEntry.recycle(); //<---- PROBLEM HERE

                    dataEntry = nextChild;
                }
                this.put(thisKey, options);
                nextCat = navData.getNextCategory();
                keyCat.recycle();
                keyCat = nextCat;
            }
        } catch (NotesException e) {
            e.printStackTrace();
        } finally {
            try {
                navData.recycle();
                vwData.recycle();
                database.recycle();
            } catch (NotesException e) {
            }
        }
    }

    public List<SelectItem> get(String key) {
        return this.get(key);
    }
}

解决:

解决方案非常简单(感谢 Sven Hasselbach 提醒我再次查看服务器日志输出)。改变很简单——交换这条线:

            nextCat = navData.getNextCategory();

为了这:

            nextCat = getNextSibling(keyCat);

虽然“getNextCategory”是ViewNavigator的一个方法,没有任何参数;它只获取当前条目之后的下一个类别。如果当前条目已被回收 - 就像上面的情况一样 - 那么显然当前条目为 null 并且该方法会引发异常。

“getNextSibling”有一个可选的 ViewEntry 参数,如果指定,它将覆盖指向当前 ViewEntry 的指针,否则它将使用它。

我责怪星期五。

4

1 回答 1

1

首先查看您的服务器控制台:您在那里看到 NotesException 吗?如果您遇到异常,您的put将永远不会被执行,因此您的组合框将为空。

在回收对象之前,您必须测试它是否为null,并被 try/catch 块包围。有一些实现可以更轻松地回收 Notes 对象,例如http://openntf.org/XSnippets.nsf/snippet.xsp?id=recycleobject-helper-for-recycling-of-objects

关于回收的一个很好的解释可以在这里找到:http: //nathantfreeman.wordpress.com/2013/03/21/recycle-and-the-retail-experience/

于 2013-03-22T10:58:08.753 回答