【问题标题】:Issue of object.recycle, and when to do itobject.recycle 的问题,以及何时执行
【发布时间】:2014-09-07 03:41:03
【问题描述】:

我在回收Notes对象方面一直相当严格,但是我遇到了无法回收对象的情况,因为它是从方法传递回调用代码的。所以在课堂上我有这个代码:

public Database getAppDB() {
            Database appDB = null;
            try{
                Session s = ExtLibUtil.getCurrentSession();
                serverName = s.createName(s.getCurrentDatabase().getServer()).getCommon();
                appDB = s.getDbDirectory(serverName).openDatabaseByReplicaID(this.getAppRepID());
                return appDB;
            }catch (NotesException e){
                System.out.println(e.toString());
                return appDB;
            }finally{
                Utils.recycleObjects(s);
            }

        } 

这会打开一个数据库,然后将 appDB 传递回调用程序。显然,如果我在调用程序中实例化数据库,我将需要回收它,但在这个类方法中,我无法回收它,因为它正在被传回。我是在用这个制造一个定时炸弹吗?如果是这样,有没有办法解决这个问题?该方法在会话的生命周期内可以被调用数百次。

【问题讨论】:

  • 只是为了好奇 - getAppRepID() 中有什么?
  • 此方法是 AppProperties 类的一部分,它存储在字符串类型的 HashMap 中,对象 HashMap 存储一个或多个应用程序定义(请参阅stackoverflow.com/questions/24746448/…)所以 getAppRepID 得到当前应用程序数据库副本 ID 的值。 AppProperties 类存储了关于可以从主数据库调用的每个应用程序的几条信息。通过使用这种方法,我可以重用我的大部分 XPage 和自定义控件。 90% 的应用程序设计在主数据库中是通用的。

标签: java xpages recycle


【解决方案1】:

简单地说:调用你的方法的代码负责回收数据库对象。 此规则也适用于 SSJS 代码!

您也不能回收会话,因为它会回收从它派生的所有对象。

【讨论】:

    【解决方案2】:

    Session 在每个请求结束时被回收,所有的后代(数据库、视图、文档等)都会被回收。我只倾向于在循环和 DateTimes 中回收 Documents 或 ViewEntries。要回收的另一件事是,如果您使用 .getColumnValues(),请将其传递到 Vector 并使用 Session.recycle(Vector) 回收列值。即使您只获得一列值,它也会全部获得。因此,如果您有一个日期列,它将被创建为 DateTime,并且回收它的唯一方法是使用 Session.recycle(Vector)。不要将其与 Session.recycle 混淆,后者会回收 Session 本身。见http://www.intec.co.uk/go-green-and-recycle-the-important-information-any-non-java-xpages-dev-needs-to-know/

    我现在首选的回收方法是使用 OpenNTF Domino API 并让它为我回收。

    【讨论】:

    • 所以如果我在 JAVA 中这样做: private Vector colVal; ..... colVal = ve.getColumnValues(); .... session.recycle(colVal);然后我需要做会话回收。 SSJS 也一样吗?
    • 您不需要回收会话本身。是的,SSJS 也是如此
    • IBM 文档中几乎完全没有回收问题,这真是令人惊讶。我从未见过 session.recycle(object)。我在我的代码中发现了几个实例,因为这可能是灾难性的,但是,在某些 SSJS 中,我将此代码作为组合框的值: var rtn:Array = database.getView("vwWFSApplications").getColumnValues(0);返回 rtn.unshift("");根据您所说的,我应该做一个 session.recycle(rtn) 但它是返回值并且会丢失。在这种特殊情况下,所有列值都只是字符串,但是.....
    • 如果列都是字符串,则不需要回收。我会写一篇关于发生了什么的博客文章并链接到它。
    • 感谢 Paul - 刚刚浏览了 Mastering XPages 这本书,recycle 甚至没有出现在索引中。
    【解决方案3】:

    虽然严格执行 .recycle() 调用是个好主意,但在这种情况下,这不太重要。无论您调用该例程多少次,如果 getAppRepID 返回相同的replicaID,您将继续获得绑定到相同C++ 句柄的数据库。因此,您可能拥有的最大打开句柄数是您在 Map 中拥有的条目数。一旦操作完成并且 Session 回收,它拥有的所有数据库句柄也将被回收。

    鉴于如今大多数服务器操作系统允许的 C++ 句柄数约为 180,000,您的扩展可能是安全的。这是所有并发请求的 180,000 个,所以如果这个过程同时发生在 1000 个用户请求中并且您将 200 个数据库放入 Map 中,您会遇到问题,但我猜这不太可能。

    或者您可以只使用 OpenNTF Domino API,这将为您完全消除此问题,并让您删除代码中的每个 .recycle() 调用。

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      相关资源
      最近更新 更多