|
|
このテクニカルノートでは Open Transport の割り込み対応メモリ管理システムの動作原理とあなたのソフトウェアで効果的に利用する方法を説明します。
このテクニカルノートは、Open Transport のクライアントまたはカーネルコードを開発する上級プログラマを対象にしています。
[2001年1月9日]
|
OT メモリ管理入門
Open Transport は割り込み時に呼び出し可能なメモリ割り当てルーチンを多数用意しています。OTAllocMem、OTAllocMemInContext、OTAlloc、OTAllocInContext、OTAllocSharedClientMem、OTAllocPortMem です。どんな場合にどのルーチンを使えばよいか(また、こうしたルーチンが Open Transport や Mac OS 管理下のメモリにどう影響するか)を知るには、OT のメモリ管理システムを理解する必要があります。
強力なメモリプール
OT メモリ管理は 4 つのメモリプールの上位に位置します。
- クライアントプールは InitOpenTransport(または InitOpenTransportUtilities)を呼び出したプログラムにそれぞれ割り当てられます。そのプログラムの OT メモリ割り当て要求を満たすもので、プログラムが CloseOpenTransport を呼び出すと(明示的またはアプリケーションの終了で)破棄されます。
- 共有クライアントプール(ネイティブプールとも呼ばれる)は最初のプログラムが(通常は AppleTalk プロトコルスタックがブートシーケンスの最初のほうで)InitOpenTransport を呼び出すと割り当てられます。OT のクライアントライブラリが割り当てるメモリの大部分はこのプールを使用します。
- カーネルプールは、OT カーネルのロード時に割り当てられます。これは OT カーネルやプラグインが使用します(例えば STREAMS のモジュールやドライバ。)
- ポートプールはプログラムがはじめて InitOpenTransport または InitOpenTransportUtilities を呼び出すと割り当てられます。このプールはポートに関する情報を保持します。これはカーネルプールとは違います。ポートスキャナは、カーネルをロードしなくても(つまりカーネルプールがなくても)使えます。
Open Transport メモリプールは Apple Shared Library Manager(ASLM)TStandardPool クラスで実装され、このクラスの属性のいくつかを継承します。
- どのプールも常に Mac OS メモリマネージャのゾーンに割り当てられます。
- どのプールにも初期サイズがあります。
- メモリプールは割り込みに対応しています。OT メモリプールからはいつでもメモリを割り当てることができます。しかし、システムタスク時にしかプールを拡大することはできません。このため、割り込み時にメモリを割り当てると、要求を満たすのに十分なメモリがゾーン内にあっても、割り当てに失敗する場合があります。
- メモリが足りなくなると、メモリプールはシステムタスク時に Mac OS メモリマネージャからメモリを割り当てます。メモリプールは一定のパーセント単位で追加されていきます。これを増加率と呼びます。増加率は最小増加量を下回ることはありません。
- プールが拡大されるのは空きスペースが下限を下回った場合です。上限もあり、これを上回るとプールは縮小を開始します。この機能はカーネルプールだけが利用します。
|
注意:
Open Transport は ASLM のメモルプール機能を利用していますが、Open Transport の今後のバージョンは ASLM をまったく使わなくなります。その際 Open Transport のメモリプールは Open Transport 自体が実装することになります。
|
|
註:
Mac OS SDK CD の ASLM SDK の ASLM Developer's Guide には ASLM メモリプールクラスについてもっと詳しい説明があります。
|
プールパラメータ
次の表に各種 Open Transport メモリプールの基本的なパラメータを示します。
|
プールの種別
|
ゾーン
|
初期値
|
増加率
|
最小増加量
|
下限
|
上限
|
|
クライエント [1]
|
アプリ
|
2K
|
20%
|
2K
|
1K
|
無限
|
|
クライエント [2]
|
システム
|
1K
|
20%
|
2K
|
512
|
無限
|
|
共有 [3]
|
システム
|
2K
|
20%
|
4K
|
2K+1
|
無限
|
|
共有 [4]
|
システム
|
3K
|
20%
|
4K
|
3K+1
|
無限
|
|
カーネル [6]
|
システム [9]
|
4K [5]
|
20%
|
34K
|
34K+1
|
[10]
|
|
カーネル [7]
|
システム [9]
|
250K
|
20%
|
34K
|
34K+1
|
[10]
|
|
カーネル [8]
|
システム [9]
|
16K
[5]
|
20%
|
34K
|
34K+1
|
[10]
|
|
ポート
|
システム
|
2K
|
20%
|
1K
|
1K+1
|
無限
|
註:
- この行は、OT アプリケーションライブラリ(名前が「App」で終わるもの)をリンクするクライアントプログラムで、InitLibraryManager を呼び出していないものです。
- この行は、OT エクステンションライブラリ(名前が「Extn」で終わるもの)をリンクするクライアントプログラムで、InitLibraryManager を呼び出していないものです。
- Open Transport 1.3 以前
- Open Transport 2.0 以降
- こちらで詳しく解説されています。
- Open Transport 1.3 以前
- Open Transport 2.0 から 2.5 まで
- Open Transport 2.6 以降
- OT は、仮想メモリの観点から、カーネルプールのメモリを明示的にホールドします。他のプールのメモリのホールドは保証されません。
- OT カーネルプールは下記に示すいくつかの要因にしたがい、拡大または縮小します。
|
重要:
上記からもわかるように、メモリプールのパラメータは予告なく変更されることがありますので、これらの値に依存してはなりません。
|
OT メモリの効果的な利用法
このセクションでは、OT メモリ管理システムを効果的に利用するヒントやコツを紹介します。
OT ルーチンとプールの使用法
次の表はメモリ割り当てを行う OT の一般的なルーチンをまとめたものです。それぞれの割り当て量、割り当て先のプールを示します。
|
ルーチン
|
プール
|
概算割当量
|
|
OTAllocMem
[1],
OTAllocMemInContext
|
クライエント
|
size パラメータに従う
|
|
OTAllocMem [1]
|
カーネル
|
size パラメータに従う
|
|
OTAlloc
|
クライエント
|
ref と fields パラメータに従う
|
|
OTAllocSharedClientMem
|
共有
|
size パラメータに従う
|
|
OTAllocPortMem
|
ポート
|
size パラメータに従う
|
|
OTOpenEndpoint
|
クライエント
共有
ポート
|
16 bytes
150 bytes
1 KB
|
|
OTStreamOpen
|
共有
カーネル
|
40 バイト
1 KB
|
|
OTCreateConfiguration
|
共有
|
100 バイト [2]
|
|
OTSnd
|
カーネル
|
n バイト [3]
|
|
重要:
ここに示した量は概算です。使用中のプロトコルの相対的な複雑さや Open Transport のバージョンによっても異なります。プログラムのメモリ使用量を解析する指針として掲載しました。
|
Notes:
- OTAllocMem はリンクするライブラリによって動作が異なります。OT クライアントライブラリ(例えば OpenTransportLib)とリンクすると OTAllocMem はクライアントプールからメモリを割り当てます。OT カーネルライブラリ(OpenTptModuleLib など)とリンクすると OTAllocMem はカーネルプールからメモリを割り当てます。OTAllocMemInContext などの“InContext”で終わる OT ルーチンは勘違いをおこすことはありません。詳しくはテクニカルノート 1173“Understanding Open Transport Asset Tracking”をご覧下さい。
- 正確な値は構成の複雑さによります。ここに示した値は OTCreateConfiguration("serial") への単純な呼び出しによる下限の値です。
- このメモリが消費されるのは、エンドポイントが送信データをコピーする場合(ACK で放出される)だけです。これがデフォルト設定です。コピーしないで送信する設定であれば、このルーチンはごく少量の管理目的のメモリを割り当てるにすぎません。
MacsBugs でメモリプールを調べる方法
上記の解析は、各ルーチンを繰り返し呼び出しながら各メモリプールへの影響を記録することで得られた帰納的なものです。OT にはメモリプールの利用状況を測定するプログラミングインタフェースはありませんが、MacsBug を使うと簡単に調べることができます。
まず、OT のウェブページ から Open Transport のデバッグバージョンを入手し、インストールパッケージから「OT Debugger Prefs」ファイルを取り出します。
Open Tpt Debug Installer
Open Transport Installer
Open Transport Files
OT Debugger Prefs
「OT Debugger Prefs」ファイルをあなたのマシンの「MacsBug Preferences」フォルダにコピーして、マシンを再起動します。
|
重要:
「OT Debugger Prefs」ファイルは、あなたがインストールした OT のバージョンと合致するバージョン番号を持つ OT のデバッグインストーラから取り出すことが重要です。「OT Debugger Prefs」ファイルには、OT ビルドシステムから自動生成された MacsBug テンプレートが含まれ、これは OT のデータ構造体のフィールドレイアウトに適合しています。OT のバージョンが違うとレイアウトも違います。誤ったバージョンの "OT Debugger Prefs" ファイルを使うと、MacsBug で正確な結果は得られません。
|
「OT Debugger Prefs」ファイルをインストールしたら、各種 OT メモリプールを探して内容表示が可能です。最初に、OT グローバル領域を表示します。68K と PowerPC では、方法が異なります。それぞれ以下のセクションで示します。
PowerPC で OT グローバル領域をダンプする
PowerPC では次のコマンドで OT グローバル領域をダンプします。
>>> dm __gOTGlobal OTGlobal
Displaying OTGlobal at 0006BDA0
0006BDA0 fGestaltValue 0000003F
0006BDA4 f68KDeferredProc 00000000
0006BDA8 fVersion 01308000
[... 以下省略 ...]
0006BF04 fClientGlobal
0006BF04 fClientList
0006BF04 fHead 005F1714
[... 以下省略 ...]
0006BF30 fNativePool 00095320
[... 以下省略 ...]
0006BF8C fKernelGlobal
0006BF8C fKernelPool 0039A4A0
0006BF90 fKernelPoolMaxSize #13421772
[... 以下省略 ...]
0006BFD4 fPortPool 0037AA90
[... 以下省略 ...]
|
OT はそのグローバル領域のアドレスを CFM シンボル、__gOTGlobal としてエクスポートします。上記のコマンドは「OT Debugger Prefs」の OTGlobal テンプレートを使ってそのアドレスをダンプします。メモリの利用状況に関していえば、次の 3 つのフィールドが関係します。
fNativePool -- 共有クライアントプールのアドレス
fKernelPool -- カーネルプールのアドレス
fClientList.fHead -- OT クライアントリストの先頭。リストの最初のクライアントは次のコマンドでダンプできます。
>>> dm 5f1714 RegisteredClient
Displaying RegisteredClient at 005F1714
005F1714 fLink
005F1714 fNext 005F15BC
005F1718 fProviders
005F1718 fHead 005F13D0
005F171C fStreams
005F171C fHead 00000000
005F1720 fWhoAmI 070A7134
[... 以下省略 ...]
|
次のクライアントは fLink.fNex フィールドを辿れば調べることができます。fWhoAmI があなたのアプリケーションヒープを指すのがあなたのアプリケーションです。自分のアプリケーションを見つけたら、TLibraryManager テンプレートを使って fWhoAmI ポインタをダンプして、ASLM との接続情報を表示できます。
>>> dm 70a7134 TLibraryManager
Displaying TLibraryManager at 070A7134
070A7134 __vptr 003873B0
070A7138 fPool 070A6780
070A713C fLibraryFile 00000000
070A7140 fDefaultPool 070A6780
[... 以下省略 ...]
|
クライアントプールのアドレスは fDefaultPool フィールドに保持されています。
プールのアドレスがわかるとそれでさまざまなことができます。
- 次の MacsBug コマンドはプールに関する基本的な情報を表示します。
>>> dm 70a6780 TMemoryPool
Displaying TMemoryPool at 070A6780
070A6780 __vptr 00386F40
070A6784 fMemList 070A6770
070A6788 fSize #2408
070A678C fLowMark #1797
070A6790 fHighMark #4294967295
070A6794 fMaxUsed #352
070A6798 fCurFree #2056
070A679C fZone 06F7CF00
070A67A0 fMemType #1
[... 以下省略 ...]
|
fSize フィールドはプール内のメモリの総量です。fCurFree はプールに残る空きメモリ量です。
- dumppool dcmd は、次のようにプール内のメモリブロックのリストを表示します。
>>> dumppool 70a6780
Allocated Memory
----------------
70a7000( #16) 70a7010( #16) 70a7020( #168)
70a70c8( #64) "!$plnt"
70a7108( #40) "!$slst"
70a7130( #48) "!$lmgr"
Free Memory
-----------
70a67f8(#2056)
|
- dumprawpool dcmd は、次のようにより詳細なリストを表示します。
>>> dumprawpool 70a6780
Allocated Memory
----------------
F: 70a67f8(#2056)
A: 70a7000( #16) 70a7010( #16) 70a7020( #168)
A: 70a70c8( #64) "!$plnt"
A: 70a7108( #40) "!$slst"
A: 70a7130( #48) "!$lmgr"
|
68K で OT グローバル領域をダンプする
68K では手順がやや複雑になります。最初に、OT グローバル領域のアドレスを探します。これには次の MacsBug コマンドを使います。
|
重要:
以下のとおり動作させるためには、OT のデバッグバージョンをインストールして、MacsBug が FetchOTGlobalシンボルを発見できるようにする必要があります。
|
>>> hx 2800
The target heap is the System heap at 00002800
>>> il FetchOTGlobal
Disassembling from FetchOTGlobal
FetchOTGlobal
+00000 0015D5E2 LINK A6,#$0000 | 4E56 0000
+00004 0015D5E6 MOVE.L $00092434,D0 | 2039 0009 2434
+0000A 0015D5EC UNLK A6 | 4E5E
+0000C 0015D5EE RTS | 4E75
[... 以下省略 ...]
|
最初のコマンドは現在の MacsBug のターゲットゾーンをシステムヒープに切り替えます。次のコマンドは OT グローバル領域のアドレスを返す関数をディスアセンブルします。FetchOTGlobal + 4 の行で OT グローバル領域のアドレスを D0 レジスタに移しています。ここでは、OT グローバル領域のアドレスはメモリ位置の$00092434 に保存されていることがわかります。次の MacsBug コマンドでこのグローバル領域がダンプできます。
>>> dm 92434^ OTGlobal
Displaying OTGlobal at 000B5050
000B5050 fGestaltValue 0000000F
000B5054 f68KDeferredProc 00238164
000B5058 fVersion 01306007
[... 以下省略 ...]
|
OT グローバル領域をダンプできたら、あとは PowerPC と同じ方法が使えます。
クライアントプールパラメータの制御
上で説明したように、アプリケーションの OT クライアントプールは InitOpenTransport を呼び出したときにアプリケーションヒープに割り当てられます。最初、プールは非常に小さく、必要に応じて増加します。しかしこの動作はいつも必ず最適であるとはかぎりません。特に、アプリケーションで OT メモリ割り当てルーチンだけを使う場合は、それに全アプリケーションヒープを与えるべきです。割り当てルーチンが少しずつアプリケーションヒープを消費する方法は、一度に大きなブロックを与える方法より非効率的です。また、頻繁に割り込み時にメモリを割り当てていると、クライエントのメモリプールが消費されてしまい、割り当てが失敗する可能性が出てきます。
クライントのメモリプールを細かく制御する方法は2つあります
- OT メモリリザーブを利用する
- ASLM の API を使って、メモリプールを直接操作する
これらのテクニックは以下に説明します。
|
重要:
アップルは前者のテクニックを強く推奨します。Open Transport は現在 ASLM のクライエントプールをそのまま利用していますが、今後はそうとも限りません。また、将来のシステムでは ASLM 自体が存在しない可能性があります。
|
OT メモリリザーブを利用する
アプリケーションゾーンの全体を OT のメモリ割り当てに利用する、もっとも確実な方法は、OT メモリリザーブを利用することです。アプリケーションを起動した時に、大きいメモリブロックを割り当てることによって、メモリリザーブを確保します。その後、メモリが必要になった時は、まず OT を使って割り当てて、それが失敗した場合はメモリリザーブを使います。
このテクニックは OTStreamLogViewer サンプルコードバージョン 1.0.1b1 以降で OTMemoryReserve モジュールで活用されていますので、そのコードを直接利用することができます。
|
註:
OT メモリを大量に割り当てて、そしてすぐに解除する方法も考えられるかもしれませんが、この手法では期待通りの結果を得られません。メモリを解除した時点で OT のメモリ管理システムはメモリを Mac OS メモリマネージャにメモリをリリースしてしまいます。
|
ASLM API によるメモリプールパラメータの制御
|
重要:
このテクニックを利用すると、OT が ASLM を利用していることに依存するだけでなく、ASLM 自体に依存することになってしまいます。このため、アップルはこの方法を推奨しません。
|
|
重要:
InitOpenTransportInContext(Carbon または OTClassicContext による実装)を利用する場合はこのテクニックを利用することができません。
|
クライアントプールをより細かく制御するには ASLM プログラミングインタフェースを使用します。事前に ASLM との接続を初期化しておくと、InitOpenTransport は、その接続(およびそのクライアントプール)を使用し、新しく作成することはしません。ASLM 接続を使うと、クライアントプールのサイズ、割り当てる位置、増加の割合を制御できるようになります。
|
註:
ASLM でプログラミングを行うには、Mac OS SDK CD の ASLM SDK が必要です。
|
|
重要:
68K C/C++コマンドから ASLM を呼び出すには、4 バイト整数を用いてビルドしなければなりません。
|
このテクニックを使うには、InitOpenTransport の前に InitLibraryManager を呼び出さなければなりません。また、CloseOpenTransport の後に CleanupLibraryManager を呼び出す必要があります。これらのルーチンのプロトタイプは「LibraryManager.h」に定義されています。読者の便宜のため以下に掲載します。
OSErr InitLibraryManager(size_t poolsize, int zoneType, int memType);
void CleanupLibraryManager(void);
|
InitLibraryManager へのパラメータで、クライアントプールの初期サイズ(単位はバイト)、クライアントプールの位置(普通は kSystemZone、kApplicZone、kCurrentZone)、クライアントプールのメモリの種類(普通は kNormalMemory、ただしページングが安全でないときにアクセスする場合は kHoldMemory)を指定できます。
次のコードの断片はこのテクニックを示すものです。まずアプリケーションヒープ内に従属ゾーンを確保します(サイズはツールボックス用に多少メモリを残したヒープの残り全部。)次に、InitOpenTransport を呼び出す前に、InitLibraryManager で ASLM に接続します(そして先のゾーンをクライアントプールとします。)
// 重要:
// このコードを利用することで、ASLM に依存してしまいます。
// このため、アップルでは推奨していません。
static OSStatus InitOpenTransportWithMemoryLimit(void)
{
OSStatus err;
SInt32 junkTotalFree;
SInt32 contigFree;
SInt32 zoneSize;
Ptr subsidiaryZone;
THz oldZone;
// まずシステムのメモリマネージャを呼び出し、
// ヒープ内の最大連続領域を調べる。
PurgeSpace(&junkTotalFree, &contigFree);
zoneSize = contigFree - kBytesReservedForToolboxInApplicationZone;
// そのブロックにメモリを割り当てゾーンを作成する。
// 続いて ASLM を初期化し、そのゾーン全体(ASLM の
// オーバーヘッドを除く)を占めるプールの作成を依頼する。
// 最後に OT を初期化する。
// すでに ASLM が初期化されているので、OT は ASLM が先の
// ゾーンに作成したプールで OTAllocMem の要求に応える。
subsidiaryZone = NewPtr(zoneSize);
oldZone = GetZone();
// InitZone は現在のゾーンを新しく作成したゾーンに設定するので、
// 自分で行う必要はない。
InitZone(nil, 16, subsidiaryZone + zoneSize, subsidiaryZone);
err = InitLibraryManager(zoneSize - 2048, kCurrentZone, kNormalMemory);
if (err == noErr) {
err = InitOpenTransport();
if (err != noErr) {
CleanupLibraryManager();
}
}
SetZone(oldZone);
return err;
}
|
|
重要:
このコードは、DTS サンプルコードの OTStreamLogViewer を簡単にしたものです(エラーチェックを減らしました。)このコードを使う場合はサンプルの元のコードを入手してください。
|
|
註:
上記のテクニックは ASLM API を使って行える唯一の方法とはかぎりません。詳細は『ASLM Developer's Guide』を参照してください。
|
上級編
このセクションでは、OT メモリ管理の関連事項のうち上級編を取り上げます。特に、共有クライアントプールやカーネルプールが時間が経過するにしたがい、拡大、縮小する様子を説明します。ただしその前に、OT メモリシステムの動作を変更する API について学ぶ必要があります。
|
註:
このセクションは Open Transport アーキテクチャの深い知識を持つ人のための参考用に書きました。理解できなくても気にしないでください。
|
OTSetMemoryLimits
OTSetMemoryLimits を使うとソフトウェアから OT メモリプールの動作を直接変更することができます。このルーチンのプロトタイプは次のとおりです。
#ifdef __cplusplus
extern "C" {
#endif
extern OSStatus OTSetMemoryLimits(size_t growSize, size_t maxSize);
#ifdef __cplusplus
}
#endif
|
growSize パラメータは今すぐ OT にそのサイズまでカーネルプールを拡大することを指示します。このルーチンを呼び出すと、OT はただちにカーネルプールをその値まで増加させます。maxSize パラメータはカーネルプールの新しい最大値です。OT はこの値を超えてカーネルプールを拡大することはありません。
OTSetMemoryLimits は同時に、Open Transport の内部変数 fServerMode を設定します。OTSetMemoryLimits を正の値の growSize で呼び出すと、fServerMode は増加します。growSize がゼロだと fServerMode は減ります。fServerMode がゼロ以外だと、OT は共有クライアントプールやカーネルプールを縮小することはしません。行儀のいいサーバソフトウェアとなるには、起動時に OTSetMemoryLimits で正の growSize を指定し、終了時には growSize にゼロを指定すべきです。
最後に、カーネルプールを 20K 以上増やすと、OTSetMemoryLimits は共有クライアントプールも growSize の値の 10% だけ増やします。
OTSetMemoryLimits は極端にバースト(連続送受信)の多い接続パターンや並行して多数の接続を受け付けるサーバソフトウェアのみが使用するものです。カーネルプールの最大サイズを増やすと、サーバは多数の並行する接続に対応することができます。カーネルプールをすぐに増大させることで(接続があるたびではなく)、サーバは、利用状況に応じてカーネルプールが増大するのを待つことなく、並列の接続でも開始後ただちに受け付けることができます。カーネルプールの縮小を禁止すると、長時間の待機状態の後でも同時に多数の接続に対応できます。
OTSetMemoryLimits はシステムタスク時に呼び出さなければなりません。指定量までカーネルプールを拡大できない場合はエラーが返されます。
|
重要:
OTSetMemoryLimits は個々の接続の性能を上げることはありません。この関数は数十の接続を並行して持つソフトウェアでしか有効ではありません。DTS はクライアントソフトウェアが OTSetMemoryLimits を呼び出すことはおすすめしません。
|
|
註:
OTSetMemoryLimits ルーチンは Open Transport のヘッダファイルにはありません。このルーチンを使う場合は自分でプロトタイプ宣言をしてください。ヘッダに入れていない理由は上記の方針からきています。一般のアプリケーションプログラムはこのルーチンを呼び出すべきではないからです。
|
|
註:
OTSetMemoryLimits の前身にあたる OTSetServerMode という関数があります。このルーチンは OTSetMemoryLimits に完全に取り込まれました。
|
OT メモリプールの拡大
OT は、バイナリ・バックオフ・アルゴリズムを用いてプールを拡大します。まず Mac OS メモリマネージャに 1 個の大きなメモリブロックを要求します。そのサイズのブロックが取得できないと、要求サイズを半分にして再試行します。この動作を要求どおりのプールの拡大に成功するか、ブロックサイズが 10K より少なくなってしまうまで繰り返します。
OT メモリプールの縮小
OT メモリプールは縮小可能です。メモリプールは Mac OS メモリマネージャから割り当てた複数の不連続なメモリブロックからなります。プールを縮小する場合は、Mac OS メモリブロックがそれぞれ空かどうか検査します。空であれば、そのメモリブロックは Mac OS メモリマネージャに返却します。
OT メモリプールは次の場合に縮小されます。
- クライアントが終了し(CloseOpenTransport を呼び出すか、呼び出さずにアプリケーションが終了する場合)、OT がサーバモードでないと、OT は共有クライアントプールとカーネルプールを減らします。
- OT がクライアントライブラリをアンロードするとき、共有クライアントプールを減らします。
- OT がカーネルをアンロードするとき(InitOpenTransport を呼び出しているクライアントが 1 つもなくなったとき)、サーバモードでなければ、カーネルプールを減らします。
- OT がカーネルユーティリティライブラリをアンロードするとき(InitOpenTransportUtilities を呼び出しているクライアントが 1 つもなくなったとき)、OT はポートプールを減らします。
- OT はポートスキャナの実行後、ポートプールを減らします。
- OT は、コンフィグレータのリストを辿り、その OTSetupConfigurator または OTStartupConfigurator エントリポイントを呼び出した後ただちに、共有クライアントプールを減らします。
カーネルプールに関するその他の詳細事項
OT はカーネルプールサイズの上限に固定の限界値を設定しています。クライアントはこの限界値を OTSetMemoryLimits ルーチンで設定できます。ここで疑問がわきます。限界値の初期値はなんでしょう。インストールの直後には、OT はこれをマシンの物理メモリ(gestaltPhysicalRAMSize で調べる)の 10% に設定します。この値は、ネットワークソフトウェアに十分なバッファ空間を与えつつ、OT がユーザの全メモリを消費しないようバランスを取った結果です。
カーネルを最初にロードすると、OT は上記の初期値でカーネルプールを作成します。しかし、カーネルがロードするたびに(最初のときも含めて)、OT はロードを完了する前に少なくとも 96KB だけカーネルプールを増加させます。これは、カーネルがアンロードされているときはカーネルプールを小さくし、ロードの際にはすばやく増加させるためです。
要約
Open Transport は信頼性のある柔軟で割り込みに対応したメモリ管理システムです。動作原理を理解することで、陥りがちな失敗を避けながら、しかも割り込み時にメモリを割り当てるコードを書くことができるようになります。
参考文献
変更履歴
|