7

関数を使用して、構成ドキュメントにアクセスします。

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

別の方法では、この関数を使用してドキュメントを取得します。

Document wDoc = this.lookupDoc(key1);

if (wdoc != null) {
    // do things with the document
    wdoc.recycle();
}

Documentオブジェクトをリサイクルするときに、DatabaseオブジェクトとViewオブジェクトをリサイクルする必要がありますか?または、関数がドキュメントを返す前にそれらをリサイクルする必要がありますか?

4

3 に答える 3

21

ベストプラクティスは、作成されたスコープ内ですべてのDominoオブジェクトをリサイクルすることです。ただし、オブジェクトをリサイクルすると、その「下」にあるすべてのオブジェクトが自動的にリサイクルされます。したがって、この例のメソッドでは、 wDbをリサイクルできません。これは、wDocもリサイクルされるため、リサイクルされたドキュメントハンドルを返すことになります。

したがって、メモリリークが発生していないことを確認する場合は、オブジェクトを逆の順序でリサイクルすることをお勧めします(たとえば、最初にドキュメント、次にビュー、次にデータベース)。これには、必要なことをすべて実行するように、またはメソッドがハンドルを取得するメソッド内でDominoオブジェクトを使用して、メソッドを構造化する必要がある傾向があります。

たとえば、構成ドキュメントを取得するメソッドを定義した理由は、そこから構成設定の値を取得できるようにするためだと思います。したがって、ドキュメントを返すメソッドの代わりに、アイテムの値を返すメソッドを定義する方がよいでしょう。

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を使用します。
  • 戻りオブジェクト(ドキュメント自体ではなくアイテム値である必要があります)もTOCで宣言されているため、例外が発生したかどうかに関係なく、メソッドの最後でそのオブジェクトを返すことができます(例外、おそらくそれはまだnullになります)。
  • この例では、すべての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>(またはString [])を受け入れ、結果の値のMap <String、Object>を返すことをお勧めします。このようにして、データベース、ビュー、およびドキュメントの単一のハンドルを確立し、必要なすべての値を取得してから、返されたアイテムの値を実際に使用する前にDominoオブジェクトをリサイクルできます。

于 2012-06-22T17:07:03.163 に答える
0

これが私が実験しているアイデアです。ティムの答えは素晴らしいですが、私にとっては他の目的のためにドキュメントが本当に必要だったので、これを試しました。

Document doc = null;
            View view = null;
            try {
                Database database = ExtLibUtil.getCurrentSessionAsSigner().getCurrentDatabase();
                view = database.getView("LocationsByLocationCode");
                doc = view.getDocumentByKey(code, true);
                //need to get this via the db object directly so we can safely recycle the view
                String id = doc.getNoteID();
                doc.recycle();
                doc = database.getDocumentByID(id);

            } catch (Exception e) {
                log.error(e);
            } finally {
                JSFUtils.incinerate(view);
            }
            return doc;

次に、これを呼び出すメソッドでdocオブジェクトを安全にリサイクルしていることを確認する必要があります

于 2015-01-02T09:52:29.317 に答える
0

config docsとしてしばらく存在し、その後は不要になった一時的なドキュメントがあるので、削除してください。これは、既存のNotesクライアントアプリケーションによって強制されます。それを満足させるには、それらが存在する必要があります。

アイテム名をキーとして、Java Date、String、DoublesのHashMapを持つクラスを作成しました。これで、ドキュメントのシリアル化可能な表現に加えて、元のドキュメントのnoteIDができたので、すぐに見つけて、不要になったときに修正/削除できます。

つまり、構成ドキュメントを収集できます。標準ルーチンは、アイテムタイプを考慮して、Java表現のすべてのアイテムのマップを作成します。その後、docオブジェクトをすぐにリサイクルできます。

戻りオブジェクトは、ドキュメントのJavaクラス表現でgetValue(String name)ありsetValue(String name, val)、valはDoubleStringまたはDateにすることができます。注意:この構造はリッチテキストや添付ファイルを必要としないため、単純なフィールド値に保たれます。

構成ドキュメントに多数のアイテムが含まれている場合は、メモリに大量の情報を不必要に保持することを意味する可能性がありますが、これはうまく機能します。しかし、私の特定のケースではそうではありません。

重要なのは、Javaオブジェクトがシリアル化可能になり、メモリに残せるようになり、Timのすばらしい回答が示唆しているように、ドキュメントをすぐにリサイクルできるということです。

于 2018-05-08T16:35:09.790 に答える