文書番号: 402074
最終更新日: 2004/04/27
この資料は以下の製品について記述したものです。
- Microsoft(R) C/C++ Development System for MS-DOS(R) and Windows(TM)Version 7.0A
- Microsoft(R) Visual C++(TM) Development System Professional Edition forWindows(TM) Version 1.0
- Microsoft(R) Visual C++(TM) Development System Standard Edition forWindows(TM) Version 1.0
概要
この資料は、C/C++ 7.0A と Visual C++ 1.0 の仮想メモリ関数についての
機能、制限事項について説明しています。
詳細
仮想メモリに関して、つぎの 10 個の関数が用意されています。
初期化と終了処理
_vheapinit、_vheapterm
仮想メモリ領域の確保と開放
_vmalloc、_vfree、_vrealloc
仮想メモリブロックのロード
_vload、_vlock,
その他
_vmsize、_vlockcnt、_vunlock
仮想メモリ関数(以下 VM 関数)を利用することによって以下のような利点があります。
-
今までコンベンショナルメモリに制限されていたメモリ割当空間を仮想メモリ
( XMS、EMS、DISK) に割り当てることによりメインメモリ以外の広い領域に 64K
単位で使用可能なだけの仮想メモリ領域にメモリブロックを割り当てることがで
きる。
-
仮想メモリ領域に XMS、EMS を指定することにより、高速なアクセスが可能。
制限事項
-
一つの仮想メモリブロックに割り当て可能な最大メモリ 65530(0xffff - 6) byte
-
一つのメモリブロックに対する最大ロックカウント 255
仮想メモリマネージャの初期化と終了
_vheapinit 関数は、 仮想メモリ マネージャを、 仮想メモリ割り当てに備えて初期化
します。どんな仮想メモリ ブロック要求よりも前に実行されている必要があります。
Syntax: int _vheapinit( unsigned dosmin, unsigned dosmax,
unsigned swaparea );
swaparea: _VM_EMS, _VM_XMS, _VM_DISK, _VM_ALLSWAP
dosmin には仮想メモリマネージャ(以下 VMM )が必要とするコンベンショナルメモリの
最小値を指定します。MS-DOS のコンベンショナルメモリにこれ以上の空きがないと
_vheapinit 関数はエラー( 0 )をかえします。
dosmax には VMM が必要とするコンベンショナルメモリの最大値を指定します。こ
の値が大きければ、メインメモリにスワップ可能なエリアが広がりますが、VMM
以外で使えるメモリが減ります。子プロセス等を起動する場合は注意が必要です。
_vheapinit で指定された swaparea は _VM_ALLSWAP を指定した場合、
_VM_XMS -> _VM_EMS -> _VM_DISK の順番で全ての領域の合計を仮想メモリ領域とし
て使用することができます。また、OR '|' で区切ることによって任意の複数のス
ワップエリアを確保することができますが優先順位は _VM_ALLSWAP に準じま
す。_VM_DISK のスワップ先は環境変数 TMP で指定されたパスになります。
_vheapterm によって仮想メモリマネージャの使用を終了します。_vheapterm は
一回の _vheapinit に対して必ず一度必要になります。
_vmalloc、_vrealloc、_vmsize、_vfree
_vmalloc は仮想メモリの初期化が終了した後に呼び出すことができます。一度に最大
64K- (マイナス) 6 バイトの大きさの領域を割り当てることができます。64K-6
バイトを越える大きさを指定すると、_vmalloc は _VM_NULL を返します。
_vmalloc は指定したバイト数以上の大きさを割り当てることがあります。注 1) 現
在割り当てられている領域の実際の大きさを調べるには _vmsize を使いま
す。_vmalloc は割り当てられたメモリ領域に対して、一つのハンドルを得ま
す。このハンドルを用いて仮想メモリにアクセスし、メインメモリ上にその空間の
データを以下に説明する_vload 等を用いてコピー(もしくは、スワップ)させ、実
際のデータにアクセスすることが可能になります。_vmalloc により得られたハン
ドルだけではデータにアクセスすることはできません。
_vmalloc で割り当てられたメモリ領域を開放するには _vfree を使います。
_vrealloc は _vmalloc で割り当てられた領域の大きさを変更します。
_vload、_vlock
仮想メモリブロックのデータにアクセスするには _vload、_vlock を使って、メインメ
モリ上に仮想メモリ領域を取り込む必要があります。プログラマは _vload、_vlock
によって返された far ポインタを利用して実際のデータを参照、更新することが
できます。
_vload によってメインメモリ上に確保された領域は後の _vload、_vlock が使用する
領域のために VMM によって自動的に破棄される可能性があります。メインメモリ上の
データを破棄したくない場合は _vlock によって領域をロックしておく必要がありま
す。
dirty フラグ
_vload、 _vunlock 関数には、パラメータに dirty フラグを指定します。_vload 、
_vunlock された領域にたいして他のメモリ領域が上書きしにいく場合( VMM によっ
てスワッピングが起こった場合)、dirty フラグによって以前のデータを仮想メ
モリ上にスワップさせるか、破棄させるかを決定します。スワッピングは、次の
タイミングで起こります。
-
_vload によってロードされた領域を別の _vload、_vlock が使用する場合。
-
_vunlock の後に、以前ロックされていた領域を _vloa、 _vlock が使用する場合。
dirty フラグで _VM_CLEAN が指定されていた場合、スワッピングが発生したときに
以前のメモリ上の内容は破棄されます。_VM_DIRTY が指定されていた場合、メモ
リ上の内容は仮想領域に書き出されます。
_vunlock、 _vlockcnt
_vlock によってロックされていた領域は、_vunlock によってロックを解除する
ことができます。また、_vlock はひとつのハンドルに対して 256 回までロック
することができます。ロックされた回数だけ _unlock しなければ、そのハンドル
によって割り当てられている領域はスワップアウトされることはありません。ハン
ドルのロックされている回数を調べるのには _vlockcnt を使います。
VMM が使用するグローバル変数
VMM が使用するグローバル変数を以下に示します。ただし、以下に記述されてある
グローバル変数は公開されていないものですので、次期バージョンにおいて利用
できなくなる可能性があります。ご注意ください。
unsigned _near cPageDos
-
MS-DOS メモリのページ数( EMS/UMB は含まれない)
int _near fVmSwapping
-スワップ領域の確保が成功している場合、フラグは TRUE
char _near fVmDisableDisk
-
VMM が 環境変数 TMP で指定されたディレクトリを使用することができなかった
場合、フラグは TRUE
int _near fhVm
-
スワップファイルが確保されているか、もし確保されていればそれが失敗してい
るか、成功しているかの値が示される。
char _near fVmDisableEms
-
VMM が EMS メモリを使っていなければフラグは TURE
char _near fVmDisableXms
-
VMM が XMS メモリを使っていなければフラグは TURE
int _near segVmDos
-
MS-DOS ヒープ領域のセグメント int _near fVmInitialized
-
VMM が初期化されている場合、フラグは TRUE
unsigned _near cVmPage
-
EMS に確保されていないページ数
// Sample Code
/*
* Compile options needed: None
*/
#include <stdio.h>
#include <stdlib.h>
#include <vmemory.h>
#include <malloc.h>
extern unsigned _near cPageDos;
extern int _near fVmSwapping;
extern char _near fVmDisableDisk;
extern int _near fhVm;
extern char _near fVmDisableEms;
extern char _near fVmDisableXms;
extern int _near segVmDos;
extern unsigned _near cVmPage;
extern int _near fVmInitialized;
void main()
{
_vmhnd_t handle;
unsigned long block_size, mem_size;
mem_size = _memavl();
printf("\nPre-vm mem avail for malloc = %u\n", mem_size);
if (!_vheapinit(0, _VM_ALLDOS, _VM_XMS))
{
printf("Could not initialize virtual memory manager.\n");
exit(-1);
}
printf("value of cPageDos = %u\n", cPageDos);
printf("value of fVmSwapping = %d\n", fVmSwapping);
printf("value of fVmDisableDisk = %d\n", fVmDisableDisk);
printf("value of fhVm = %d\n", fhVm);
printf("value of fVmDisableEms = %d\n", fVmDisableEms);
printf("value of fVmDisableXms = %d\n", fVmDisableXms);
printf("value of segVmDos = %d\n", segVmDos);
printf("value of cVmPage = %u\n", cVmPage);
printf("value of fVmInitialized = %d\n", fVmInitialized);
printf("Requesting 100 bytes of virtual memory.\n");
if ((handle = _vmalloc(100)) == _VM_NULL)
{
_vheapterm();
exit(-1);
}
block_size = _vmsize(handle);
printf("Received %d bytes of virtual memory.\n", block_size);
_vfree(handle);
_vheapterm();
}
Keywords: KBINFO KB402074
Technology: kbAudDeveloper kbVCsearch kbZNotKeyword3 kbZNotKeyword8