GetElementsByTagNameのメモリリーク

とりあえずの生存報告をかねて。

.NETのXmlDocumentでGetElementsByTagNameを使用したときにメモリリークっぽい現象を見つけたのでメモ。

もともとサーバで動くAPでOutOfMemoryExceptionが発生したのでいろいろと調べたところ下のようなコードを書いているところでやたらとメモリとついでにリソースも食いつぶしていた。

Private Doc As XmlDocument
Public Sub Hoge()
Dim ndlst as XmlNodeList
ndlst=Me.Doc.GetElementsByTagName("hogetag")
End Sub

調査に使ったのはCLRProfilerで、数日ほどずっと動かした結果を見たところRelocaled bytesのHistogramというグラフで

System.Xml.XmlNodeChangedEventHandler
System.Xml.XmlElementListListener

というオブジェクトが大量に残っていることが分かり、さらにGC Handle StatisticsのHandles survivingでも残りっぱなしの状態だった。呼び出しツリーを追ってみるとGetElementsByTagNameの内部で上記2つのオブジェクト全て生成されていたのでたぶん原因はこれ。

そもそもこのXmlDocumentオブジェクトは普通のXML操作と違って設定情報読み込み用で、AP起動中はずっと存在し続けるし、毎回XMLデータを取得するようになっているので使い方としてはもっと改善がいる気はする。設定用のエンティティオブジェクトに移送するとか。

とはいえMSDNによるとこのメソッドは推奨されなくなっていたので、ためしにSelectNodesに書き換えたらメモリリークもなくなったのでとりあえず解決。あ、.NETのバージョンは2.0なのでそれ以降は改善されているかも。

SQLは設計か実装か

いくつかのいわゆる詳細設計書をみてて思ったこと。なお、詳細設計書が不要!というのはまた別の話ということで。

SQLは簡単に言うとデータベースからデータ持ってきたりデータを放り込んだりするものだけど、最近思うのがレイヤ間のデータやり取りなんだから、コンポーネント間のインターフェース仕様とかと同じく、設計書に書くんなら一緒に書くべきじゃないかという気がしてきた。

モデルとデータストアとのインターフェース仕様=SQLという認識でもいいんじゃないかと。

MercurialのSSH接続

たまにしか使わないといつのまにか忘れてしまっていたのでメモ。

  1. PuTTYのPagentを起動。
  2. AddKeyで接続先のPPKファイルを選択。
  3. 接続のためのパスワードを聞かれるので入力。
  4. ViewKeysで選択したキーがあればOK。

あとはTortoiseHgとか直接hgコマンド叩くなりして操作。

忘れていると、「遠隔ホストの応答が不適切」というエラーになる。

新しい院外処方箋のレイアウトについて

2010年4月から院外処方箋のレイアウトが変わる(まぁ経過措置はあるけど)。

都道府県番号、点数表番号、医療機関コードを印字しないといけないのだが曲者は点数表番号。

厚労省の資料では医科が1、歯科が3としか書かれていないのだが・・・労災は?そのまま1か3だけ?

医療機関コードって労災のときは違うから労災保険指定のときは印字内容変えないといけないけど、点数表番号は1か3でいいのか?

1週間きってるけど疑義照会にもまだ載ってないし、疑問は膨らむ。

MS Project Server 2007のSQL認証ではまったところ

ActiveDirectoryを立てられなかったのでSQL認証で構築したけど、はまった点が2つあったのでメモ。

1)ユーザ設定で使うPjFormsAuthUpgrade.exeについて

ユーザ設定用の空XMLを生成する以下のコマンドは問題なく動いた。

PjFormsAuthUpgrade.exe -createemptyusersfile -log form.log –url http://servername:port/pwa -usersfile users.xml

でも、XMLを登録するコマンドはURLが違いますといわれてなぜか動かない。

PjFormsAuthUpgrade.exe -log form.log –url http://servername:port/pwa -usersfile users.xml
Error http://servername:port/pwa not specified.

対策は二つ。一つはコマンドのオプション指定順を以下のようにするらしい。
もう一つはサーバを再起動する。本当です、これで一括登録のバッチが何も変えずに動くようになりました。

PjFormsAuthUpgrade.exe -usersfile users.xml -log form.log –url http://servername:port/pwa

2)SQL認証用のデータベース権限

手順の一番最初にSQL認証用のDBをSQLServerに以下のコマンドでつくる。

aspnet_regsql.exe /A m /E

手順はこれであっているのだけど、ユーザ設定も終わり最後の認証用Webアプリからサインインしようとすると
「不明なエラー」ではじかれる。

散々調べまわった結果、イベントログにSQLSERVERの認証エラーがでていた。
接続ユーザは「NETWORK SERVICE」だったので、SQLServerのログインユーザ権限を確認したところ、aspnetdbにはpublicしかなかった。
ということでaspnet_で始まるロールを割り当てて無事ログイン完了。

もしかしたらweb.configのConnectionStringで直接ユーザとパスワードを指定しても動きそうな気がする。


特に2は手順として致命的な気がするけど誰もはまったことがないんだろうか?Webにもそれらしい記述が見つからなかったけど・・・。

外来端末とユーザログイン

外来に限らないけれども、とりあえず外来中心で。

外来のバックヤード(診察室の裏とか処置室周辺あたり)は相当忙しいので、オーダリングや電子カルテが導入されているところでは使用者の切り替えがまったくなされていないのが現状。

操作ログを見ているとそれがよくわかって一人の主任看護師(一般看護師権限でないのがポイント)さんのIDだけが朝から夕までログインしっぱなしだったということはよくある話。

とりあえず診察待ちや処置待ちなどが一覧で見える画面があって、そこから注射実施とか処置実施の画面を開くと必ずユーザIDとパスワード(もしくはPDA3点チェックみたいに職員証読み取りとか)でログインして、操作を行って実施画面を閉じると自動でログアウトできるような、ワンアクション認証の外来業務画面とか作ればいいのに。

ntbackupでとりあえず必須にしてたほうがいいオプション

AITとかDATとかテープドライブを使ったバックアップをやるとき、複数のテープをローテーションするように運用すると、たまに2回目以降「使用されていないメディアがなかったため、この操作は実行されませんでした。」とか「指定したメディアが見つからなかったため、操作は実行されませんでした。」とかいうエラーが出てバックアップできないことがでてきます。

原因はどうやら違うメディアという認識ができなくなるらしい。ハードとOSがうまくかみ合っていないそうな。

そんなときは、ntbackupに/UMオプションをつけて実行すれば問題なくバックアップが取れるようになります。/UMはメディアプールなどのメディア管理をしないオプション(UnManagement?)なので上書きの危険はあるけど、厳密に世代化はしなくてもいいから確実に最新は取っておきたい人は必須でつけておいたほうが幸せになれます。ちなみに、Windows2003Serverのntbackupヘルプには/UMオプションが記載されていないけど問題ありません(前にヘルプだけを見てバックアップスクリプトを組んだときにこれが原因でひどい目にあった)。

詳しくはこちらWindows2000と書いてあるけど2003も同じ。ただし、2008になるとテープは時代遅れとでもいう感じでバックアップのシステム自体が変わっています。