<Return[H]><Top>

HeapCreate

Declare Function Api_HeapCreate& Lib "kernel32" Alias "HeapCreate" (ByVal flOptions&, ByVal dwInitialSize&, ByVal dwMaximumSize&)

Declare Function HeapCreate Lib "kernel32" Alias "HeapCreate" (ByVal flOptions As Long, ByVal dwInitialSize As Long, ByVal dwMaximumSize As Long) As Long

呼び出し側プロセスが使用できるヒープオブジェクトを作成する。この関数は、プロセスの仮想アドレス空間内の領域を予約し、このブロック内の指定された初期のパートに物理格納域を割り当てる。

パラメータ
flOptions
    [入力]新しく作成したいヒープのオプションの属性を指定する。それ以降、HeapAlloc、HeapFree、HeapReAlloc、HeapSize の各ヒー

    プ関数を呼び出してこの新しいヒープにアクセスする際に、これらのオプションは影響を及ぼす。次の値のいずれかまたは任意の組み合わせ

    を指定できる。

    値                                                   

意味                                                                                                                     

    HEAP_GENERATE_EXCEPTIONS

 

メモリ不足などの状況で関数が失敗したときに、NULL を返すのではなく、例外を発生させるようシステムに指示する。

    HEAP_NO_SERIALIZE

 

 

 

ヒープ関数がヒープからメモリの割り当てや解放を行うときに、相互排他を行わないよう指示する。既定では HEAP_NO_SERIALIZE フラグが指定されていないが、この場合はヒープへのアクセスがシリアル化される。この結果、複数のスレッドが同じヒープに対してメモリの割り当てや解放を同時に行える(内部ではシリアル化により、1 つずつ処理される)。

dwInitialSize
    [入力]ヒープの初期サイズをバイト単位で指定する。この値は、最初の段階でヒープに割り当てられる物理格納域(実際のメモリ)の量を

    決定する。この値は、ページ単位へ切り上げられる。ホストコンピュータのページサイズを調べるには、 関数を使う。
dwMaximumSize
    [入力]dwMaximumSize の値が 0 以外の場合、ヒープの最大サイズをバイト単位で指定する。HeapCreate 関数は dwMaximumSize

    を次のページ領域へ切り上げ、プロセスの仮想アドレス空間内で、そのサイズのブロックをそのヒープ用に予約する。HeapAlloc または

    HeapReAlloc 関数が、dwInitialSize で指定された初期の物理格納域の量を超える割り当てを要求すると、システムはヒープの最大サイ

    ズを超えない限り、そのヒープに物理格納域の追加ページを割り当てる。
    加えて dwMaximumSize に 0 以外の値を指定した場合、ヒープはそれ以上拡張されることがないし、絶対的な限界も設定される。ヒープ

    内の各メモリブロックの最大サイズは、0x7FFF8(10 進の 524,280)バイトより少し小さなサイズに制限される。このサイズを超えるブロックの

    割り当てを要求すると、たとえヒープがそのブロックを収容できる十分な大きさであっても、その割り当ては失敗する。
    dwMaximumSize に 0 を指定した場合、ヒープが拡張可能になる。ヒープのサイズは、利用可能なメモリによってだけ制限される。

    0x7FFF8 バイトを超えるブロックの割り当てを要求しても、自動的に失敗することはない。システムはそのような大きなブロックが必要とする

    メモリを取得するために、VirtualAlloc を呼び出す。大きなメモリブロックを割り当てる必要があるアプリケーションでは、dwMaximumSize

    に 0 を指定する。

戻り値
    関数が成功すると、新しく作成されたヒープのハンドルが返る。
    関数が失敗すると、NULL が返る。拡張エラー情報を取得するには、 関数を使う。

解説
    HeapCreate 関数は、HeapAlloc 関数を使って、プライベートヒープオブジェクトを作成する。呼び出し側プロセスは、このオブジェクト内でメ

    モリブロックの割り当てを行える。初期のサイズは、最初にそのヒープへコミットされるページ数を決定する。最大サイズは、予約済みページ

    の合計ページ数を決定する。これらの予約済みページは、プロセスの仮想アドレス空間内に 1 つのブロックを作成し、ヒープはそのブロック

    内で拡張できる。HeapAlloc 関数を使って、現在のコミット済みページ数を超える割り当てを要求した場合は、物理格納域が利用可能で

    ある限り、予約済みの空間へ追加のページが自動的にコミットされる。
    プライベートヒープオブジェクトのメモリにアクセスできるのは、そのヒープを作成したプロセスだけである。ダイナミックリンクライブラリ(DLL)がプ

    ライベートヒープを作成した場合、そのヒープはその DLL を呼び出したプロセスのアドレス空間内に作成され、そのプロセスだけがそのヒープ

    にアクセスできる。
    システムは、ヒープを管理するための構造体を、ヒープへコミットされたメモリ内に格納する。したがって、プロセスは、指定したヒープサイズ

    すべてを利用できるわけではない。たとえば、HeapAlloc 関数を使ってあるヒープを作成し、最大サイズとして 64 キロバイト(KB)を指定した

    場合、64KB の割り当てを要求すると、システムのオーバーヘッドが原因でその割り当てに失敗することがある。
    HEAP_NO_SERIALIZE を指定しない場合(既定)、呼び出し側プロセスからヒープへのアクセスはシリアル化される。シリアル化を有効にす

    ると、複数のスレッドが同じヒープでメモリブロックの割り当てまたは解放を行おうとしたときに、相互排他が保証される。パフォーマンスは多

    少低下するが、複数のスレッドが同じヒープでメモリの割り当てまたは解放を行う場合は、必ずシリアル化を有効にしなければならない。
    HEAP_NO_SERIALIZE の値を指定すると、ヒープの相互排他が無効になる。シリアル化が無効な場合、共通のヒープハンドルを使う複

    数のスレッドがメモリの割り当てまたは解放を同時に行う可能性があり、その場合はヒープが壊れてしまう。そのため、

    HEAP_NO_SERIALIZE を安全に利用できるのは、次の条件のいずれかが成立する場合だけである。
    •プロセスがただ 1 つのスレッドを使っている。
    •プロセスが複数のスレッドを使っているが、特定のヒープに対してヒープ関数を呼び出すのはただ 1 つのスレッドである。
    •プロセスが複数のスレッドを使っているが、アプリケーションは特定のヒープで相互排他を実現するための独自のメカニズムを用意している。
    注意 アクセス違反を防止するために、構造化例外処理を使って、コードがヒープへの書き込みや読み取りを行うことを禁止する。