2012年9月27日木曜日

メモリリークしてる?

topコマンドで、OpenSimを動かしているmonoのメモリ使用量モニタしてるんですが、時間の経過とともに徐々に大きくなってきます。ちなみに、OpenSimのバージョンは、OSgrid OpenSimulator 0.7.5.dev.224efe7です。

起動直後は次のような感じ(COMMANDがmonoのところのSIZEとRESに注目)。
last pid: 20123;  load averages:  0.47,  0.27,  0.15        
81 processes:  1 running, 80 sleeping
CPU:  4.7% user,  0.0% nice,  2.2% system,  0.1% interrupt, 93.1% idle
Mem: 457M Active, 1969M Inact, 218M Wired, 2676K Cache, 112M Buf, 349M Free
Swap: 2048M Total, 3360K Used, 2045M Free

  PID USERNAME  THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
20105 opensim    51  46    0   336M   255M ucond   3   1:10 15.23% mono
 1673 mysql      17  44    0   192M 45720K sbwait  1  17:33  0.00% mysqld
...
... 以下省略
...

だいたい51時間後は、次のような感じ。メモリ使用量がほぼ倍になってます。
last pid: 20086;  load averages:  0.20,  0.15,  0.10
83 processes:  1 running, 82 sleeping
CPU:  1.3% user,  0.0% nice,  3.0% system,  0.0% interrupt, 95.7% idle
Mem: 734M Active, 1947M Inact, 212M Wired, 2740K Cache, 112M Buf, 99M Free
Swap: 2048M Total, 3368K Used, 2045M Free

  PID USERNAME  THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
78208 opensim    54  44    0   619M   515M ucond   3 563:00  8.30% mono
 1673 mysql      16  50    0   192M 45708K sigwai  2  17:32  0.00% mysqld
...
... 以下省略
...
「opensim メモリリーク」で検索してみたら 、Kimiko Dover さんの「Opensimで、メモリーリークが起きているのかな? 」って記事がヒットしました。メモリ使用量増加の割合もだいたい同じぐらいです。

このペースでメモリ使用量が増えたら、ほかにもサービス動いてるし、ちょっとこのマシンでは苦しいなぁ...。問題が根本的に解決されるまで、定期的に再起動かけるようにするかな。ハードウェア共用のVPSとかをレンタルされている方は苦しいかもしれませんね。

2012年9月23日日曜日

OSG48に参加しました

OSG48とは、OSGridに接続している日本人オーナーのリージョン郡です。私も、このリージョン郡へお誘いをうけて、参加させていただきました。当初1つのリージョンだけのつもりだったんですが、「何事も経験だからまとめて引越ししたら?」との事で、それじゃあ、ということで4つまとめて移動してきました。

周りにたくさんのリージョンがあります。お隣さん、よろしく!


 お隣の高い山のリージョンから自分のリージョンを眺めるの図。


いまのところ、安定してるとは思うけど、昨日物理オブジェクト400個だしたら、core dumpしてOpenSimが死んでしまった。ODEには、まだなんか潜在的な問題があるのかなぁ? それともOpenSimの側の使い方の問題?

OpenSimが死んだとき、自動的にリカバリーする仕組み、そろそろつくらないと...。


2012年9月21日金曜日

ODE 0.12にアップデイト

いままで、ODE(Open Dynamics Engine)は、FreeBSDのPorts(devel/ode)のものを使ってました。このバージョンは 0.11.1です。いま、ODEプロジェクトのホームページを確認したら、0.12がでていました。0.11.1が出たのが 2009-10-17で、0.12が2012-05-28 ですので、いろいろとバグが修正されていることが期待できます。まだ、Portsは0.11.1のまんまなんで、ここは手動でソースコードからライブラリをインストールすることにします。

automakeをインストール

ODEのコンパイルには、automakeが必要ですので、Portsからインストールします。
# cd /usr/ports/devel/automake && make install clean
依存関係のあるPortsもあわせてインストールされますが、まあ、気にしない。
automakeはODEをコンパイルする為だけに必要で、実行時には必要ありません。

ソースコード取得とパッチあて

ODEのサイトの download のリンクをたどると、sourceforgeのサイトにいきます。そこから、「ode-0.12.tar.bz2」をダウンロードし、展開します。ダメなら、ブラウザ等でいったんダウンロードしてから、FreeBSDに転送します。
# fetch http://sourceforge.net/projects/opende/files/ODE/0.12/ode-0.12.tar.bz2
# tar xvzf ode-0.12.tar.bz2
...
... ファイルが展開される
...

展開したソースコードのMakefile.amに次のパッチを当てます。こちらからダウンロードするか、コピペして、「ode-0.12_freebsd.patch」というファイル名で保存してください。
--- Makefile.am.orig    2012-02-12 07:03:27.000000000 +0900
+++ Makefile.am 2012-09-19 21:24:49.000000000 +0900
@@ -40,5 +40,5 @@
         CHANGELOG.txt INSTALL.txt README.txt LICENSE.TXT \
         bindings

-pkgconfigdir = $(libdir)/pkgconfig
+pkgconfigdir = $(libdir)data/pkgconfig
 pkgconfig_DATA = ode.pc
このパッチを当てないと、monoがlibode.soを見つけられなくてエラーになります。odeのソースコードがFreeBSDの devel/pkgconf の仕様に適合してない為みたいです。

# cd ode-0.12
# patch -p1 < /some/where/ode-0.12_freebsd.patch

configure & make

パッチがあたったら、sh autogen.shを実行して、configureスクリプトを作成します。
# sh autogen.sh
次にconfigureスクリプトに、次の引数をつけて実行します。
# ./configure --disable-asserts --enable-shared --disable-demos --with-drawstuff=none CFLAGS="-O2 -msse -march=i686" CXXFLAGS="-O2 -msse -march=i686"
CFLAGSとCXXFLAGSに「-O2 -msse -march=i686」をつけているのは、IntelCPUのSSE命令などをつかって、ちょっとでも最適化し、性能を上げようとしてます。サーバーのCPUのアーキテクチャにあわせて、適切なものに変えるといいかもしれません(どのくらいパフォーマンスが稼げるのかは不明)。

では、ソースコードをmakeし、エラーがなければインストールします。
# make
...
... 
# make install
...
...
インストールが完了したら、OpenSim.exeを再起動します。エラーなく起動されればOK。

動作確認

さて、うまくうごいているか動作を確認してみます。
まずは、CUBE を500個だし、物理属性をつけます。


 だんだん崩れていきます。


 ぺっちゃんこになりました。


さすがに、500個も物理オブジェクトを出すと、身動きがとれません。ちなみにOpenSimを動かしているコンピュータは、Intel ATOM D525、メモリ4GBです。


 CUBEの中を歩き回ります。まともに動けませんけど、OpenSimは落ちないみたいです。


この時の、topコマンドによるプログラムの状態は、次の通りです。
last pid: 86961;  load averages:  1.13,  0.77,  0.48                                           up 5+10:20:55  01:07:55
93 processes:  2 running, 88 sleeping, 3 stopped
CPU: 25.5% user,  0.0% nice,  2.3% system,  0.0% interrupt, 72.1% idle
Mem: 503M Active, 2020M Inact, 224M Wired, 61M Cache, 112M Buf, 188M Free
Swap: 2048M Total, 2528K Used, 2045M Free

  PID USERNAME  THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
86679 opensim    53  44    0   413M   322M ucond   3  10:17 104.98% mono
 1673 mysql      16  50    0   192M 45656K sigwai  2   7:24  0.00% mysqld
 2242 opensim     1  44    0 11900K  8732K select  0   0:54  0.00% screen
68091 opensim     1  44    0  3688K  1688K CPU2    1   0:04  0.00% top
 1685 root        1  44    0  3384K  1120K nanslp  1   0:04  0.00% cron
 1460 root        1  44    0  3352K  1096K select  1   0:03  0.00% syslogd
.....
.....
.....
重いのは重いけど、sshで接続しているセッションは普通に操作できます。
また、私のリージョンサーバーは、現在4つのリージョンがあるのですが、CUBEをぶちまけた隣のリージョンにテレポートしたら、そこでは普通にうごけました。

また、500個も物理オブジェクトをぶちまけると、次のような警告がOpenSimのコンソールに沢山でます。
01:04:41 - [PHYSICS]: Physical Object went out of bounds.
01:04:41 - [PHYSICS]: Physical Object went out of bounds.
...
... 途中省略 ...
...
01:05:01 - [PHYSICS]: Physical Object went out of bounds.
01:05:03 - [PHYSICS]: Physical Object went out of bounds.
01:05:03 - [PHYSICS]: Physical Object went out of bounds.
Region (root) #

これらのオブジェクトは、地面の下にもぐっていたり、リージョン境界でぐるぐるまわってたり、隣のリージョンまでいってしまってたりします。ビュアーのArea Search等で、オブジェクトを探して、一つ一つ削除していかないといけなくなります(>_<)。作業を簡単にするため、あらかじめ物理オブジェクトには、検索しやすいような名前をつけておくことをお勧めします。

まとめ


まだ、もっと様子をみないといけないけど、ODEがいきなり落ちてしまうということはなくなったかもしれません。

2012年9月16日日曜日

プロセスのメモリ上限を増加させた(ODEがエラーで落ちた)

ODEがエラーで落ちるという件ですが、プロセスが使えるメモリ上限が少ないためにでていたのかもしれません。OpenSimのサイトの次のページを見てみると、Linuxの場合プロセスが使うスタックの最大サイズを262144KBにしろとあります。
http://opensimulator.org/wiki/PhysicsEngines
In Linux you should consider using included shell script, opensim-ode.sh or type ulimit -s 262144 before running mono OpenSim.exe if you plan on having a large number of physics objects (each avatar is a physics object, as well as those which have the physics flag set on the simulator). The ulimit -s 262144 in Linux protects you against stack collisions and corrupted memory when there are a large amount of physical objects roaming around.
(個々のアバターは、物理オブジェクトと同じ扱い)
 
 FreeBSDの場合、カーネルパラメーターでプロセスが確保できる、データサイズ、スタックサイズ等の上限が設定されています(これ以上は指定しても増えない)。
# sysctl kern.maxdsiz kern.maxssiz
kern.maxdsiz: 536870912
kern.maxssiz: 67108864
このサイズはすべてのプロセスの最大値なので、すべてのプロセスはこの上限を超えてメモリを確保することはできません。プロセス毎に小さく設定することはできます。また、子プロセスは親プロセスのリソース制限を(ファイルディスクリプタや、環境変数などと同じように)継承します。

現在のプロセス(というか対話しているshell)のリソース制限値は次のようにして調べられます(limit, ulimit という csh, sh の内蔵コマンドでも表示できる)。
# /usr/bin/limits
Resource limits (current):
  cputime              infinity secs
  filesize             infinity kB
  datasize               524288 kB
  stacksize               65536 kB
  coredumpsize         infinity kB
  memoryuse            infinity kB
  memorylocked         infinity kB
  maxprocesses             5547
  openfiles               11095
  sbsize               infinity bytes
  vmemoryuse           infinity kB
  pseudo-terminals     infinity
  swapuse              infinity kB
これをみると、データーサイズ 524288KB、スタックサイズ 65536KBで、OpenSimのサイトの注意書きにあるスタックサイズ262144 KBにくらべて小さすぎることがわかります。

大きくするには、/boot/loader.conf に次のように設定します。
#
# for OpenSim ODE(Open Dynamic Engine).
# ODE require  262144KB or more Stack Size.
# 
kern.maxdsiz="1024M"
kern.maxssiz="512M"
(#はコメントなのでいらないけど、後でなぜそうしたのかわかるように書いておくほうが吉。)
まあ、これだけ大きければOKかも。でも大きいということは、メモリリークするプログラムとかがあった場合、検出するまでに時間がかかったり、検出した時点では、システムのメモリ使い尽くしてしまっててOSごと落ちるということもないとは言えないので、ある意味慎重に設定したほうがいいとは思います。

こうしておいて、OpenSimを立ち上げると、140個ぐらいの物理属性つけたCUBE をぶちまけても落ちなくなりました。ただし、そのリージョンではすべての動作が遅くなり、すごく重くなります。まあ、すべてのフレームにおいて、物理オブジェクトの位置と回転を計算し、その変化した位置情報をビュアーにUDPパケットで送らないといけないので、CPUも使うし通信するデータ量もかなり増えてしまうからなんだろうとは思いますが....。OpenSim.iniのパラメータをいじったら、すこし緩和できたりするのかしら?






 ただ、落ちなくなるといっても限界があり、260個ぐらいだして、ぶちまけたCUBEのなかをアバターで歩き回るとやはり前のようなエラーがでました。
ODE INTERNAL ERROR: disabled body tagged
Stacktrace:

  at (wrapper managed-to-native) Ode.NET.d.WorldQuickStep (intptr,single) <0xffffffff>
  at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x01383>
  at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00029>
  at OpenSim.Region.Framework.Scenes.Scene.Update (int) <0x004af>
  at OpenSim.Region.Framework.Scenes.Scene.Heartbeat () <0x000bf>
  at System.Threading.Thread.StartUnsafe () <0x00059>
  at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) <0xffffffff>
Abort (core dumped)
この、「ODE INTERNAL ERROR: disabled body tagged」ってのが出る条件が良くわからない。中身を理解するのは、私のレベルでは無理だけど、エラーがでて、システムがとまってしまうのは困るなぁ...。

2012年9月15日土曜日

ODEがエラーで落ちた

物理オブジェクトいじってたら、次のようなエラーでOpenSimが落ちた(>_<)。
Region (Neo Galapagos) #
ODE INTERNAL ERROR: disabled body tagged
Stacktrace:

  at (wrapper managed-to-native) Ode.NET.d.WorldQuickStep (intptr,single) <0xffffffff>
  at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x01383>
  at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00029>
  at OpenSim.Region.Framework.Scenes.Scene.Update (int) <0x004af>
  at OpenSim.Region.Framework.Scenes.Scene.Heartbeat () <0x000bf>
  at System.Threading.Thread.StartUnsafe () <0x00059>
  at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) <0xffffffff>
Abort (core dumped)
私のコンパイルしたODEには、まだ問題があるのかなぁ...。

ちなみに、OpenSimのバージョンは、opensim-dd0556a。

OSGridのリージョンを増やしました

OSGridのOpenSimサーバーがそれなりにうごいているみたいなんでリージョンを増やしてみました。リージョン増やすのは、bin/Regions/Regions.ini に記述を増やし、リージョン毎に別のInternalPortを割り当てればOKです。具体的な方法はこちらが参考になります。


ちなみに、この4つのリージョンは、メガリージョンにしていません。いちどメガリージョンにしてみたんですが、土地区画を分割したときに、あとで追加したほうのリージョン内の区画で音楽URLは設定できるけど、その区画に入ったときにビュアーの音楽が切り替わらないという現象がありました。そういうわけで今のところメガリージョンにしてません。設定項目とかに抜けがあるのかもしれませんので、確認して後日再挑戦してみることにします(^_^;)。

この状態でmonoのメモリの使用量は SIZE=470MB, RES=371MB、CPU使用率は3-5%、メモリは4GB積んでるんで、まだ余裕あります。CPUは、物理オブジェクトを動かすと急に使用率が増えます。物理オブジェクトが無い状態だと、2-3%以下なんですが、物理なBOXオブジェクトを7個ほど出すと、15~20%に跳ね上がります。CPUがATOM D525なんで、CPU負荷がかかるようなのはつらいのかもしれません。まあ、でもこの程度なら、まだまだ大丈夫かな?



このうちの一つのリージョンをOSG48という日本人オーナーのSIM郡に接続してもらう予定です(OSGrid 48だと思う。なんで48なのかは不明。48リージョンつなげるぞーーってことなのかな? ちなみにオレオレ詐欺48ではないwww)。

2012年9月2日日曜日

OSGridのすごいSIM

OSGridは、基本的に自分で設定したOpenSimをテストするグリッドという意識があったので、あまりうろうろはしてませんでした。でも、自分のOpenSimが接続できたので、しばらくぶりにうろうろしてみたところ、けっこう完成度の高いリージョンがちらほらあったりします。

次のスクリーンショットは、Laniというリージョンの宇宙ステーションで撮ったものです。宇宙ステーションの中は全部つながってて、かなり広い空間になっています。SecondLifeでこういうSIMを所有しようとすると、(金銭的に)かなり大変ですけど、OpenSimだと十分可能です。






ただ、まだまだアルファレベルのソフトウェアなんで、普通の人が簡単にというわけにはいきません。また、SLとちがって、人があんまりいないし、イベントもなさそうなんで、なんらかの目的意識がないとまったく面白くないかもしれません。まあ、SecondLifeの完成度になるには、まだまだ時間がかかるとは思います(SecondLifeとは方向性がちがうけどね)。

まあでも、試しにアカウントとってINしてみるのも面白いかもしれませんね。