fc2ブログ

NSD : Top 10 - Process memory usage

前回は共有メモリの占有率の高いブロックを特定する方法について紹介しました。
今日は同様にして、プロセスメモリを見る方法を確認してみましょう。


基本的には共有メモリと同じなので、以下のようなフォーマットになっています。


#------ Top 10 [ nserver:116c] Memory Block Usage:
BY SIZE | BY HANDLE COUNT
Type TotalSize Handles | Type Handles TotalSize
---------------------------- | ----------------------------
0x0149 43472 8 | 0x0130 119 43316
0x0130 43316 119 | 0x0380 72 33552
0x0380 33552 72 | 0x030a 48 16128
0x0317 20728 11 | 0x0910 41 3512
0x0146 17408 1 | 0x0275 38 4408
0x030a 16128 48 | 0x0f02 28 3080
0x0128 10480 1 | 0x4129 14 0
0x0275 4408 38 | 0x0317 11 20728
0x02c6 4096 1 | 0x0149 8 43472
0x0910 3512 41 | 0x0f5d 2 220
-----------------------------------------------------------


最新のバージョンではこのようなフォーマットになります。
手元にあるのがクライアントのNSDだけだったので、クライアントのものを掲載します。
<@@ ------ Notes Memory -> Usage Summary -> Top 10 Memory Block Usage -> 16 bit Handles By Size :: [ nlnotes: 0bc4] (Time 17:07:00) ------ @@>

Type TotalSize Count Typename
-----------------------------------------------------------
0x024b 9833602 341 BLK_OPENED_NOTE
0x0c01 6496596 203 BLK_DOC
0x2f0d 3227452 261 BLK_LSWRAP_SCRIPT
0x0149 1506376 267 BLK_PHTCHUNK
0x1803 1217220 25 BLK_DESK_DESIGNLIST
0x0b85 1189898 145 BLK_ACTION_POOL
0x11b3 719448 11 ???
0x1803 689688 12 BLK_DESK_DESIGNLIST
0x0307 484160 10 BLK_INDEXENTRIES
0x0a04 261624 4 BLK_NET

<@@ ------ Notes Memory -> Usage Summary -> Top 10 Memory Block Usage -> Memhandles By Size :: [ nlnotes: 0bc4] (Time 17:07:00) ------ @@>

Type TotalSize Count Typename
-----------------------------------------------------------
0x4129 7864320 15 BLK_LOCAL
0x0440 596714 9807 BLK_SITEMAP_DATAENTRY
0x0168 393248 3 BLK_LOCAL_BLOCK
0x2f0e 224062 189 BLK_IDE_DVECTOR
0x0f66 147370 1835 BLK_RSRCLNK_DATA
0x10af 131074 1 BLK_NEM_STATBAR_MSG_TO_FILE
0x0b0d 125922 274 BLK_TOKENEDIT
0x0c24 65054 12 BLK_GR_SEGBITS
0x0bc3 56062 110 BLK_ACTION_PANE_EVENT_ENTRY
0x0f67 50438 670 BLK_RSRCLNK_SERVERHINT




それぞれの列は以下のように理解します。

Type: メモリブロックの種類をあらわす16進の数値
TypeName: 上のタイプに付けられている名前
TotalSize: 実際にアロケートされているサイズ(バイト)
Count: 使用されている数

TypeとTypeNameが前回も分かりにくく感じたかもしれないですが、これは数字で表記するか文字で表記するかだけの違いだと思ってもらえればいいんじゃないかと思います。

ちなみに、Type で0x4129のように、0x4000 を含むものはマスクしてあると考えてください。
なので、0x4129は0x0129と同じです。
0x8000は共有メモリをあらわしますが、0x4000はここでは単純にプロセスヒープと言う意味ではなく、別の意味を持つのですが同じものだ、と言う事が分かれば十分なのでここでは置いておきます。

NSDもだいぶ回を重ねてきて見れる場所が増えてきたのではないでしょうか。
でもNSDはまだまだあります。



NSD: Shared OS fields (MM/OS structure)

今日はNSD の中でも、Shared OS Fields についてお話します。
この呼び名は、6.5.4以前のNSDで使われていたもので、6.5.5以降ではこのセクションは MM/OS tructure と呼ばれています。

 なんだか全然違う名前に変わっているし、どちらも名前からが意味を想像しにくくて分かりにくいのですが、クラッシュのNSDでは、ここは「クラッシュ情報」のようなものを表示するセクションだと思ってください。
 それにしても何でこのような名前なのでしょうか。どちらも「OS」と言う言葉が使われていますが、やはり大多数の人がこの名前を聞くと、オペレーティングシステムの事を想像してしまいますが、実はそうではありません。
 実際には、OSと言うのは、NOS = Notes Object Service の意味で使われています。これがNotesではメモリー管理やスレッド管理などを担って結果としてOSの違いを吸収するレイヤーになるので、オペレーティングシステムと誤解してもある程度意味が通ってしまうのですが、この辺もつまづきのもとですね。
 もう一つ出てきた「MM」はもちろん「マジむかつく」の意味ではなく、「Domino Memory Management」の意味になります。これを統括する部分はMMM (MM Manager)と呼ばれたりします。
 つまり、このセクションは、MMやOSと言う重要な構造体のサマリー情報を表示する事を目的としている部分です。結果としてクラッシュなどの重要な情報も含んでいます。

出力を見てみましょう。

 6.5.4以前
------ Shared OS Fields -------

Start Time = 11/16/2005 07:54:40 PM
Crash Time = 11/16/2005 08:04:07 PM
SharedDPoolSize = 1000000
FaultRecovery = 0x00010013
Thread [ nAMgr:0bb8:0002]/[ nAMgr:0bb8:0b1c] (bb8/2/b1c)
caused Static Hang to be set
ConfigFileSem = ( SEM:#0:0x010d) n=0, wcnt=-1, Users=-1, Owner=[]
FDSem = ( RWSEM:#11:0x410f) rdcnt=-1, refcnt=0 Writer=[] n=11, wcnt=-1, Users=0, Owner=[]


新しいバージョンのものは例によって自分のクライアント環境のものを使います。
 6.5.5以降
<@@ ------ Notes Data -> OS Data -> MM/OS Structure Information (Time 08:44:37) ------ @@>

Start Time = 2009/06/25 01:39:19
Crash Time = 2009/06/25 08:44:14
Console Log Enabled = 1
Console Position = 791
Error Message = PANIC: 01:92
Console Position = 791
SharedDPoolSize = 4194304
FaultRecovery = 0x00010c01
Cleanup Script Timeout= 300
Crash Limits = 0 crashes in 0 minutes
StaticHang = Virtual Thread [ nlnotes: 1340: 0002] (Native thread [ nlnotes: 1340: 12d0]) (0x1340/0x2/0x12d0)
ConfigFileSem = ( SEM:#0:0x010d) n=0, wcnt=-1, Users=-1, Owner=[ : 0000]
FDSem = ( RWSEM:#52:0x410f) rdcnt=-1, refcnt=0 Writer=[ : 0000], n=52, wcnt=-1, Users=0, Owner=[ : 0000]

色々気になる部分もあると思いますが、このセクションからは、Start Time や Crash Time、Fatal Thread 情報、Panic メッセージを確認します。
 Fatal Thread 情報はこのセクションで確認すると、仮想スレッドとネイティブスレッドの情報を一度に確認できます。
 Panicなどが出ている場合には、

Error Message = PANIC: LookupHandle: handle out of range

 のように表示されたりしますのでここの情報を確認します。


あまり頻度は多くありませんが、クラッシュしたNSDでは複数のFatalスレッドが見えることがあります。その場合には理論上はこのセクションを見て最初にFatalスレッドが発生したスレッドを確認することが出来ます。
 しかしながら、6.5.4 以前ではWindows 版のNSDではこの部分に最後にFatal スレッドを出したスレッドを記録してしまうのでこの場合にはプロセスツリーを見て、nsd.exe の親プロセスとなっているプロセスを確認します。

表示されている情報を見ると、こんなセクションをあえて見ることは無いだろう、と思ってしまうかもしれないですが、意外とここはサポートでも参照しているのです。


NSD: Open Databases セクション

今日はNSDのOpen Databases セクションです。

以前に特定のスレッドが開いているデータベースを特定する方法についてこちらで紹介しましたが、このセクションはとにかく開いているデータベースを一覧で出力しています。
VThread セクションは「このスレッドは何を開いているのか?」と言う視点であるのに対し、こちらは「あるデータベースを開いているスレッドは何か?」と言う視点で調査をするときに有用です。

まずは例によって出力を見てみます。

古いフォーマット
------ Open Databases -------

X:\Lotus\Domino\Data\mailgrp\XXTkProSup.nsf
Version = 43.0
SizeLimit = 0, WarningThreshold = 0
ReplicaID = 86256f58:006f5eb0
bContQueue = NSFPool [ 1: 28228]
FDGHandle = 0xf01c06d5, RefCnt = 1, Dirty = N
DB Sem = (FRWSEM:0x0244) state=2, waiters=0, refcnt=0, nlrdrs=1 Writer=[]
SemContQueue ( RWSEM:#0:0x029d) rdcnt=-1, refcnt=0 Writer=[] n=0, wcnt=-1, Users=-1, Owner=[]
By: [ nAMgr:0c70:0002] DBH= 471, User=CN=SERVER01/OU=SVR/O=ACME


新しいフォーマット
<@@ ------ Notes Data -> NSF Data -> Open Databases (Time 23:35:28) ------ @@>

CN=ServerXX/O=Org!!w_dir\wp\test.nsf
Version = 43.0
SizeLimit = 0, WarningThreshold = 0
ReplicaID = 0x492568f8:0x002e9cd7
bContQueue = NSFPool []
Offline = No
DeleteInProgress = No
FDGHandle = 0x00000000, RefCnt = 69, Dirty = N
DB Sem = (FRWSEM:0x0244) state=0, waiters=0, refcnt=0, nlrdrs=0 Writer=[ : 0000]
SemContQueue ( RWSEM:#0:0x029d) rdcnt=-1, refcnt=0 Writer=[ : 0000], n=0, wcnt=-1, Users=-1, Owner=[ : 0000]
By: [ NLNOTES: 02c8: 0002] DBH= 148, User=CN=Taro Yamada/O=Org
By: [ NLNOTES: 02c8: 0002] DBH= 149, User=CN=Taro Yamada/O=Org
By: [ NLNOTES: 02c8: 0002] DBH= 150, User=CN=Taro Yamada/O=Org
By: [ NLNOTES: 02c8: 0002] DBH= 152, User=CN=Taro Yamada/O=Org
By: [ NLNOTES: 02c8: 0002] DBH= 153, User=CN=Taro Yamada/O=Org
By: [ NLNOTES: 02c8: 0002] DBH= 154, User=CN=Taro Yamada/O=Org


さて、上の出力からも分かるように、ここではデータベースのフルパスが始めに出力されますが、リモートのデータベースを開いている場合には、「CN=ServerXX/O=Org!!w_dir\wp\test.nsf」のような形式でちゃんと出力されます。転送を行うRoterタスクなどがリモートのmail.boxに書き込んであるのが見えたりすることもあるのではないかと思います。


各フィールドは以下の通りです。
他にも気になる部分があるかもしれないですが、すべて公開されているわけではないので御容赦下さい。


Version: データベースのODSバージョン
SizeLimit: データベースのサイズの制限値 (KB) 0は制限なし
WarningThreshold: データベースの制限値の警告のしきい値(KB)
Replica ID: レプリカID
By: [ proc:PID:VTID] : [プロセス名: プロセスID: 仮想スレッドID]
DBH: データベースハンドル。DBを開くときに必ずこのデータベースハンドルを使用します。
User: データベースを開いているデータベース名

WriterとかOwnerとかあるのはデータベースセマフォの情報ですが、詳細はあまり公開されていないようなので触れないでおきます。(0x0244はDatabase SemaphoreをあらわすIDです。)

ここから、DB名、レプリカID、開いているユーザーやスレッドなどを特定して問題発生時のDBの使用状況などを確認します。

非常にNSDの中でも重要なセクションなので、何かDBの問題が気になるときはよく見てみましょう。

NSD: NIF Collection Users (pool)

今日はNSDのエントリの中でも「NIF Collection Users (pool)」と言うセクションについて説明します。
このセクションはひと言で言うと、ノーツが開いているビューの情報と、ビューを開いているスレッドの一覧です。 「NIF Collections」と言うよく似た名前のセクションがあるのですが、大きな違いはアクセスしているスレッド情報を確認できる事にあります。

始めにこのセクションがどのように表示されるか見ていこうと思うのですが、非常に横に長いセクションなので、表示の都合上二つに折って説明します。

古いフォーマット
------ NIF Collection Users (pool) -----
CollUserVB hColl CollID CollectionVB Remote OFlags ViewNoteID
------------ ------ ------ ------------ ------ ------ ----------
[ 8: 15364] 336 0 [ 6: 16388] NO 0x0082 758


Data HDB/Full View HDB/Full RefCnt SessionID Open By
------------- ------------- ------ ------------- --------------
339/ 343 339/ 343 1 [ 9: 4679] [ nSERVER:13e4:0055]


新しいフォーマット
<@@ ------ Notes Data -> NIF Data -> NIF Collection Users (pool) (Time 14:47:29) ------ @@>

CollUserVB hColl CollID CollectionVB Remote OFlags ViewNoteID
------------ ------ ------ ------------ ------ ------ ----------
[ 00004405] 20 0 [ 00001005] NO 0x0000 290
[ 00002005] 7 0 [ 00003005] NO 0x0000 446
[ 00002805] 22 0 [ 00003005] NO 0x0000 446


Data HDB/Full View HDB/Full RefCnt SessionID Open By
------------- ------------- ------ ------------- --------------
11/11 11/11 1 [] [ nlnotes: 1318: 0005]
6/6 6/6 1 [] [ nlnotes: 1318: 0002]
21/21 21/21 1 [] [ nlnotes: 1318: 0005]


見れば何となく意味が分かった今までのセクションと比べて、このセクションは比較的とっつきにくいのではないかと思うのですが、右端に[プロセス名:PID:仮想スレッドID] が表示されているので、ビューに関連した情報とこのスレッド情報を関連付けているセクションではないか?と言うのは分かると思うのですが、「ViewNoteID」とかで関連付ける事が出来るのは分かるのではないでしょうか?
 ちなみにNoteIDはDB内では一意ですが、複数のDB間ではもちろん重複する可能性もあるので、「このDBの中にあるこのビュー」と言う関連付けは、View HDBの情報でそのユーザー(スレッド)が使用しているデータベースハンドルが分かるのでここから特定する事が出来ます。(ちなみにスレッドがつかんでいるもの・・・・と言う切り口で見たいならVThreadセクションを使うので、あまりこの観点で広げていく事はこのセクションでは必要ありません。)

CollectionVB:
 CollectionをあらわすIDのようなものだと思ってください。実際にはCollectionのIDと言うと、hCollの値のほうがその意味に近いのですが、他のセクションとの突合せはここを使うのでここを押さえておきましょう。とにかく左から四番目の列の値をコピーして探すと関連情報が出てくる、とだけ覚えておけばいいんじゃないかと思います。

ここは実際には、ビューのコレクション情報のメモリー上の位置を示すようなものです。

Remote:
ビューがリモートのビューかローカルサーバー上(またはワークステーション上)のものであるかを示しています。

ViewNoteID:
ビューのNOTEIDです。

Refcnt:
ビューを開いているユーザーの数です。

View HDB/Full:
ビューアクセスに使用しているデータベースハンドルです。
Fullはフルアクセスを行う際のハンドルですがあまり使いません。

Open By:
そのビューを開いているスレッド情報です


NSDのNIF情報は、このセクションとNIF Collections のセクションをセットで見ることが多いので、このあとのエントリと交互に見てみると面白いのではないかと思います。

NSD: NIF Collections

NSD の記事はありがたい、と言う人と全然分からなくて面白くない、と言う人の意見が二分していていつも悩みどころなのですが日本語の情報も少ないのと自分自身どこかにまとめておきたいと言う気持ちもあるのでもう少し続けます。(ちなみにあと2-3回かなあ・・と思っています)

今日は前回紹介した「NIF Collection User」と兄弟のような関係のあるセクションです。
まずは具体的な表示を見てみましょう。
今回も表示を見やすくするためにここでは一部長い列は折り返して表示しています。

古いフォーマット
----- NIF Collections ------
CollectionVB ViewNoteID UNID OBJID RefCnt Flags Options
------------ ---------- -------- ------ ------ ------ --------
[ 14: 4100] 654 5d48dcc0 382618 5 0x0000 00000000

Corrupt Deleted Temp NS Entries ViewTitle
------- ------- ---- --- ------- ------------
NO NO NO YES 0 ($VIMPeople)

CIDB = [ 22: 27652]
CollSem (FRWSEM:0x030b) state=0, waiters=0, refcnt=0, nlrdrs=0 Writer=[]
NumCollations = 1
bCollationBlocks = [ 10: 31300]
bCollation[0] = [ 11: 50692]
CollIndex = [15061: 64855]
Collation 0:BufferSize 15,Items 1,Flags 0
0: Ascending, by KEY, "$1", summary# 1
ResponseIndex [65535: 65534]
NoteIDIndex [65535: 65534]
UNIDIndex [65535: 65534]


新しいフォーマット
<@@ ------ Notes Data -> NIF Data -> NIF Collections (Time 16:48:51) ------ @@>

CollectionVB ViewNoteID UNID OBJID RefCnt Flags Options
------------ ---------- -------- ------ ------ ------ --------
[ 00012005] 1194 7ae747 1514 1 0x4000 00000008

Corrupt Deleted Temp NS Entries ViewTitle
------- ------- ---- --- ------- ------------
NO NO NO YES 0 ($CrossCertByRoot)


CIDB = [ 00031405]
CollSem (FRWSEM:0x030b) state=0, waiters=0, refcnt=0, nlrdrs=0 Writer=[ : 0000]
NumCollations = 1
bCollationBlocks = [ 0000d365]
bCollation[0] = [ 00013005]
CollIndex = [ 00000014]
Collation 0:BufferSize 51,Items 3,Flags 0
0: Ascending, by CATEGORY, "OrgCombo", summary# 1
1: Descending, by KEY, "IssuedBy", summary# 2
2: Descending, by KEY, "IssuedTo", summary# 3
ResponseIndex [ 03eafcec]
NoteIDIndex [ 03eafcec]
UNIDIndex [ 03eafcec]


ここで、CollSemとか FRWSEM:0x030b はCollection セマフォを示しています。
これがどういうものか?と言うと説明が難しいのですが複数のスレッドからのビューの更新などで予期しない更新が入ったりしないようにするためのセマフォだと考えてください。

全ての列は出せないのですが、それぞれ以下のような意味があります。
(NIF Collection Usersと同じものは説明を流用しています。。)


CollectionVB:
 CollectionをあらわすIDのようなものだと思ってください。実際にはCollectionのIDと言うと、hCollの値のほうがその意味に近いのですが、他のセクションとの突合せはここを使うのでここを押さえておきましょう。この値からNIF Collection Users との関連付けをします。

ViewNoteID:
ビューのNOTEIDです。

Refcnt:
ビューを開いているユーザーの数です。

Deleted:
 すでに削除されたビューである事を示しています。

Temp:
一時的に作成されたビューで、ディスクに保存されないようなビューである事を示しています。

NumCollations:
 ビューの「Collation」の数なのですが、クリックしてソート可能な列などがあると増えやすいのですが、一概には言えないので、ビューの複雑さをあらわす目安だと考えてください。

Ascending/Descending:
 ビューのソートされている列が昇順(Ascending)か降順(Descending)かを示しています。


NIF Collection Usersが「どのスレッドがこのビューにアクセスしているか」と言う視点であるのに対し、NIF Collections は「着目しているビューはどのようなビューか?」と言う事について可能な限りの情報を与えるものです。

何となくビューの複雑さや列の数なども想像できますし、ソート列の数などもここから推定する事が出来ますし、アクセスが多いビューである事も分かります。

なかなか活用は難しいのですが、NSDからビュー情報も以外に色々な情報が取れることが分かってもらえればよいのではないかと思います。

NSD: Open Documents

そろそろNSDネタも尽きてきそうな気がするのですが、今回はOpen Documentsセクションについて説明します。

実はこのセクションは以前はあまり使われないセクションでした。

  以前のフォーマット

----------- Open Documents ---------
DBH NOTEID HANDLE CLASS FLAGS FirstItem LastItem
830 2302 0x1eb2 0x0001 0x0200 [ 7858: 836] [ 7858:2344]
407 2294 0x1d9f 0x0001 0x0300 [ 7583: 836] [ 7583: 948]
526 17626 0x1d0e 0x0001 0x0301 [ 7438: 836] [ 7438: 948]
714 2294 0x1ec1 0x0001 0x0300 [ 7873: 836] [ 7873: 948]
557 2294 0x1e33 0x0001 0x0300 [ 7731: 836] [ 7731: 948]
609 2294 0x1c0c 0x0001 0x0300 [ 7180: 836] [ 7180: 948]
422 2294 0x1d0f 0x0001 0x0301 [ 7439: 812] [ 7439:28120]
281 2294 0x1e16 0x0001 0x0300 [ 7702: 836] [ 7702: 948]
574 2294 0x1c34 0x0001 0x0300 [ 7220: 836] [ 7220: 948]




スレッド毎に開いている文書ならVThread セクションを見ればいいので実際に処理していない文書も出てくるし、ここで表示されている文書をどう使えばいいのだろう?と言うのもあって開いている文書のNoteIDとDB Handle だけ一覧で出されてもあまり活用できなかったのです。

これは新しいフォーマットになって以下のような詳細情報が出力されるようになって文書の詳細情報を得る事ができるようになりました。このフォーマットは主に6.5.5/7.0 以降ではこのようになっているのではないかと思います。


  新しいフォーマット
<@@ ------ Notes Data -> NSF Data -> Open Documents (BLK_OPENED_NOTE) (numDocs=17, numPools=20) :: (Shared) (Time 17:06:58) ------ @@>

DBH NOTEID HANDLE CLASS FLAGS IsProf IsAgent #Pools #Items Size Database
53 0 0x2a92 0x0001 0x0000 No No 1 1 65404 CN=mailserver/O=ACME!!mail\admin.nsf
.
Open By: CN=notes admin/O=ACME
Flags2 = 0x0000
Flags3 = 0x0000
OrigHDB = 0
First Item = [ 10898: 816]
Last Item = [ 10898: 816]
Non-pool size : 7
Member Pool handle=0x2a92, size=65404 (BLK_OPENED_NOTE)

(略)

<@@ ------ Notes Data -> NSF Data -> Open Documents (BLK_CL_OPENED_NOTE) (numDocs=77, numPools=91) :: (Shared) (Time 17:06:58) ------ @@>

DBH NOTEID HANDLE CLASS FLAGS IsProf IsAgent #Pools #Items Size Database
111 1458 0x2b62 0x0004 0x0001 No No 1 15 65404 CN=mailserver/O=ACME!!mail\admin.nsf
.
Open By: CN=notes admin/O=ACME
Form Name: ThreadMap
Flags2 = 0x0000
Flags3 = 0x0000
OrigHDB = 0
First Item = [ 11106: 816]
Last Item = [ 11106: 1080]
Non-pool size : 129
Member Pool handle=0x2b62, size=65404 (BLK_CL_OPENED_NOTE)


各列については全ては説明できませんが、大まかには以下のような意味を持っています。
 各列の意味について
DBH 開いている文書のデータベースハンドル
(DBHを使えば、Open DatabasesセクションでDB名が調べられます)
NOTEID NOTEIDです。16進表記になります。
CLASS 文書クラスです。下のテーブルを見て文書がフォームか文書か、ビューか、などが分かります・
IsProf 文書がプロフィール文書であるかどうかを示しています。
#Pools POOLというのはメモリの単位なのですが対象の文書が何個のPOOLを使用しているかを示しています
Size 文書のサイズですが、POOL内でどれだけ使用されているかを示しているものなので目安程度に見てください。
Items 該当文書が何個のアイテムを持っているかが分かります。
Database データベース名です。
Opened By 文書を開いているユーザー名です。


文書クラスは何度かこのブログでは説明していますが、以下のような意味を持っています。
別のフラグでマスクされている事もあるので、たとえば0x80004 と言う値があったら、8の意味はともかくとしてとりあえずForm Noteと思って構いません。

文書クラス
0x0001 Data Note (document)
0x0004 Form Note
0x0008 View note
0x0040 ACL Note
0x0200 Agent Note
0x0800 Replication Formula Note


文書の問題が疑われるときはちょっと見てみるといいと思います。

NSD : 開いている文書

 今日は実際にNSDを実行して結果が自明なケースを確認してみて理解を深めてみようと思います。

NSDで表示される「開いている文書」についてもう少しゆっくり考えて見ましょう。


始めにLotus Notesクライアントを開き、個人アドレス帳を開き、任意の文書をクライアント上で開いてみてください。
私のテスト環境では、NoteIDが0xF9A(=3994)の文書を探してみましょう。

VThreadを見てみます。NoteIDが0xF9Aの文書探すには、「NoteID=3394」と言うキーワードで探してみます。
多くの場合このキーワードではヒットしない事に気が付くと思います。
 確かにこの文書は開いていたはずなのに、なぜ見つからないのでしょうか。

NOTEID 3394の文書はOpen Documents のセクションで確認する事が出来ます。


<@@ ------ Notes Data -> NSF Data -> Open Documents (BLK_OPENED_NOTE) (numDocs=7, numPools=8) :: (Shared) (Time 01:59:41) ------ @@>

DBH NOTEID HANDLE CLASS FLAGS IsProf IsAgent #Pools #Items Size Database
19 3994 0x29c8 0x0001 0x0100 No No 2 185 81960 C:\Lotus\Notes\Data\names.nsf

Open By: CN=Hirotaka Nagashima/OU=Japan/O=IBM
Flags2 = 0x0400
Flags3 = 0x0000
OrigHDB = 19
First Item = [ 10696: 884]
Last Item = [ 10707: 5588]
Non-pool size : 2176
Member Pool handle=0x29c8, size=16556 (BLK_OPENED_NOTE)
Member Pool handle=0x29d3, size=65404 (BLK_OPENED_NOTE)



つまり、VThread セクションで表示されるのは正に今処理中の文書なので、UIで表示されているだけでは処理中の文書とは言えないからです。
このような文書はOpen Documents のセクションで確認する事が出来ます。逆にここでは使用されたフォームなども表示されていて、文書の表示にフォームが開かれている事が出来ます。
開いている文書、と一言で言ってしまうと誤解を読んでしまう事もあるのでこの点については手元で動きをよく見ておくと解析にも役に立つのではないかと思います


NSD: Process Memory Mapping (Windowsのみ)

(今日のトピックはプラットフォームに依存していないトピックも多いのですが主にWindowsを想定して書いています。UNIXプラットフォームをイメージすると多少変に聞こえるところがあるかもしれませんのでその点はご了承下さい)

共有メモリとかプロセスヒープとかスタックとか色々な種類のメモリがNotesに限らずプロセス内には存在する事が分かっている方は多いと思いますが、どれもスコープが違うだけで、1つのプロセスでは同じ仮想アドレス空間内に配置されます。たとえば仮想アドレス空間内では、1番地から5番地は共有メモリ、10番地から20番地はプロセスヒープ、のようになっているはずです。

NSDでは共有メモリとか色々ややこしいのが出てきますが、共有メモリはあれを含めてこれを含めないとかプロセスヒープとかもスタックは含まないとか、二つを足してもDLLやexeをロードしている領域は含まれなかったり分かりにくいですよね。全体としてはどういう風に配置されているか知りたいときにはどうすればいいのでしょうか?

Sysinternalsではこのような利用状況を把握するためにVMMAP と言うツールが提供されていますが、NSDでは、Process Memory Mapping と言うセクションにこれと同様の機能が提供されています。


NSD のProcess memory mapping から共有メモリを見ると以下のように表示されています。
Notes SMem と表示されているセクションが、mapped と言うType指定をされている事に着目して下さい。

59 00b60000 00b60000 4.2M COMMIT mapped -Crw-- 0 Notes shared mem:MMM
60 00f9f000 00000000 4.0K FREE ------- -C---- 0
61 00fa0000 00fa0000 980.0K COMMIT mapped -Crw-- 0 Notes SMem[1]
(略)
64 01120000 01120000 256.0K COMMIT mapped -Crw-- 0 Notes SMem[2]
65 01160000 01160000 256.0K COMMIT mapped -Crw-- 0 Notes SMem[3]
66 011a0000 011a0000 256.0K COMMIT mapped -Crw-- 0 Notes SMem[4]
67 011e0000 011e0000 256.0K COMMIT mapped -Crw-- 0 Notes SMem[5]
68 01220000 01220000 256.0K COMMIT mapped -Crw-- 0 Notes SMem[6]
(略)
333 084e0000 084e0000 980.0K COMMIT mapped -Crw-- 0 Notes SMem[30]

NSD の Shared Memory ではこの様子が以下のように出力されています。

Shared Memory:
TYPE : Count SIZE ALLOC FREE FRAG OVERHEAD %used %free
S-DPOOL: 30 32350292 29901108 2418644 0 47216 92% 7%
Overall: 30 32350292 29901108 2418644 0 47216 92% 7%

ここを見るとnServer のアドレス空間には nServer のイメージもロードされています。

50 00400000 00400000 4.0K COMMIT image -Cr--- 0 nSERVER.EXE
51 00401000 00400000 20.0K COMMIT image -Cr-x- 0 nSERVER.EXE (.text)
52 00406000 00400000 8.0K COMMIT image -Cr--- 0 nSERVER.EXE (.rdata)
53 00408000 00400000 4.0K COMMIT image -Crw-- 0 nSERVER.EXE (.data)
54 00409000 00400000 4.0K COMMIT image -Crw-c 0 nSERVER.EXE
55 0040a000 00400000 8.0K COMMIT image -Crw-- 0 nSERVER.EXE
56 0040c000 00400000 12.0K COMMIT image -Cr--- 0 nSERVER.EXE (.rsrc)


各スレッドのスタックのサイズも分かります。

Idx BaseAddr AlocBase Size State Type Prot Desc
---- -------- -------- ------ ------- ------ ------ ---------------
302 06c30000 06c30000 764.0K RESERVE private -C---- 0 thread 0cf0 stack (reserved)
303 06cef000 06c30000 4.0K COMMIT private GCrw-- 0 thread 0cf0 stack (guard)
304 06cf0000 06c30000 256.0K COMMIT private -Crw-- 0 thread 0cf0 stack

guardと言う領域まで延びるとAccess Violationを起こすのは何となく分かるのではないでしょうか。

このセクションは実際にNotesがメモリをどう使っているのかが直感的に分かるので、個人的には解析と言うよりは、Windowsプロセスのメモリの使い方を勉強するのに非常によく役に立ちました。


メモリの使用状況が多いときなどにはこんなセクションを見なくても、Shared、ヒープ、スタックなどを見ていった方が統計的な情報が得られるのでこのような情報は必要ないこともあるのですが、使用状況を詳細に把握したいときにはこのような情報も有益になるので、始めは興味本位でもよいので少しずつ見てみてください。

尚、最近のNSDではAIXでも似たようなセクションが表示されるようになりましたが、基本的にはWindowsのみの機能だと思ってください。

NSD: 秀丸のアウトライン解析機能で目次を作る

NSDをじっくり眺めることがある人はDominoの技術者でもあまり多くないかもしれませんが、NSDは解析しているとコールスタックセクションとmemcheckセクションを行き来しないといけないので、意外とテキストエディタの便利さは解析効率に影響します。

ここでテキストエディタのアウトライン機能を使ってNSDを構造的に把握して、目次のようにアクセスする方法について紹介します。
私は秀丸を使って行いましたが、高機能なテキストエディタなら同等の機能を持っているものも多いのではないかと思います。また秀丸でも古いバージョンでもアウトライン機能はサポートしていないかもしれません。

まず、秀丸のメニューでは、[その他]-[ファイルタイプ別の設定]から設定をします。(画像はクリックすると拡大します)ここで、左側のペインから[アウトライン]-[解析]を選択してアウトラインの設定を行います。
秀丸の設定画面

行頭の文字列で以下のように「Section: 」と「<@@ 」を設定します。(<@@の後に半角スペースを入れるのを忘れないようにしてください)

このように設定してNSDを確認すると以下のようにアウトライン枠が表示されるようになります。

Hidemaru1.png

これで右側のアウトラインからNSDのセクションにジャンプできるようになります。
また、NSDの目次のような表示にもなるので全体の構造理解にも役に立つので、NSDに慣れてないときにも理解の助けになるのではないかと思います。

興味がある方はぜひ一度試してみてください。