このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ
  • 追加された行はこの色です。
  • 削除された行はこの色です。
  • メモリ へ行く。

*目次 [#hc2dff58]

#contents


*主記憶装置とメモリ [#z920f3c7]

 [[ノイマン型コンピュータ]]では、プログラムとデータが記憶装置に置かれる。これらが処理の進行に伴ない、処理装置から逐次参照される。ここでの記憶装置のことを''主記憶装置''という。主記憶装置では、半導体記憶素子(ICメモリ)が用いられる。これは写真製版技術を使って、精密な回路を基板に焼き付けたモノである。そのため、一般的には主記憶装置といえば、''メモリ''のことを指す。


**主記憶管理の役割 [#vb778085]

 大きなプログラムで大量のデータを高速かつ複数同時並行的に処理するためには、記憶装置は主記憶装置の他に[[キャッシュメモリ]]と[[ディスク装置]]を含めて階層化されている。このうち主記憶装置とディスク装置で実現される仮想記憶の管理が主記憶管理の主要な役割である。


*RAMとROM [#p85ec4a5]

 記憶装置を大きく分けると、読み書きができる''RAM(Random Access Memory:ラム)''と読み出し専用の''ROM(Read Only Memory:ロム)''がある。

-[[RAM]]
--読み書き可能。
--発揮性。電源を切ると記憶内容が消える。
-[[ROM]]
--読み出し専用。
--不揮発性。電源を切っても記憶内容が消えない。

#img(http://security2600.sakura.ne.jp/main2/image3/RAM_ROM.jpg)
#img(,clear)

 一般に[[プログラム]]は電源を切ってもその内容を保持できるROMに入れておく。また、プログラムで用いられるデータの格納には、RAMが用いられる。

 よって、ROMは決まったプログラムの他に固定データを入れ、いつも同じ処理をする場合に使うわけである。そして、RAMはデータを記憶させる他に、プログラムを組む上での一時記憶エリア(作業エリア)としても使われる。


*メモリの語長 [#v095bbcf]

 メモリに対する1回のアクセスで読み書きできるデータを''語(word:ワード)''といい、その長さ(ビット長)をメモリの''語長(word length)''という。

 メモリの語長は、CPUの語長と等しくなっている。


*アドレス [#se723c6e]

 メモリには語長を単位にして、アドレス(番地)が付けられている。

 そして、メモリをアクセスするときには、何番のアドレスの記憶データを読み出せとか、何番のアドレスにデータを書き込めというように、アドレスを指定する必要がある。この

 アドレスは必ず0から順に割り当てられ、またROMとRAMの割り振りは自由に行うことができる。

#img(http://security2600.sakura.ne.jp/main2/image3/mom_word.jpg)
#img(,clear)


*読み出し動作と書き込み動作 [#b03d9b8b]

-読み出し動作
--「アドレスバスからアドレスを指定する」+「読み出し信号」+「データバスから読み出しデータを与える」
-書き込み動作
--「アドレスバスからアドレスを指定する」+「書き込み信号」+「データバスから書き込みデータを与える」


*記憶管理 [#c318bcc0]

 主記憶装置の利用形態は、ハードウェアおよびソフトウェア両技術の進展に伴ない、大きく変化してきた。


**再配置 [#ud7ab20c]

 ''再配置''とは、記憶領域のどの位置に読み込んでも実行できるように、プログラムの格納場所のアドレスを補正し、格納し直すことである。

 再配置は次の2つに分類できる。

-動的再配置
--プログラムを実行中に再配置すること。
-静的再配置
--プログラムの実行前に再配置を行い、実行中は位置の変更を行わないこと。

 ''再配置可能プログラム''とは、記憶領域のどの位置に読み込まれても実行可能なプログラムのことである。コンパクションを行う場合は、プログラムは再配置可能でなければならない。


**実記憶方式と仮想記憶方式 [#q98d42ee]

 コンピュータは、OSとプログラムを主記憶に読み込んでから実行する。この読み込みを''ロード(ローディング)''という。その際、プログラムに対する記憶領域の割り当てと解放を管理する機能を''実記憶管理''という。主記憶装置にある記憶領域のことを''実記憶領域''といい、この実記憶領域を利用する仕組みを''実記憶方式''という。これに対して補助記憶装置を利用して実記憶よりはるかに大きな記憶領域を利用する仕組みを''仮想記憶方式''という。

 主記憶において、仮想記憶方式を利用せず実記憶管理を行う場合には、実行するプログラムを効率的に配置することが重要になる。仮想記憶方式を利用すると、主記憶へのアクセスより補助記憶装置へのアクセスのほうが遅いため、処理速度が低下する。

-記憶管理の方式
--実記憶方式
---パーティション方式
---スワッピング方式
---オーバーレイ方式
--仮想記憶方式
---ページング方式
---セグメント方式(セグメンテーション方式)
---ページセグメンテーション方式

 仮想記憶方式は物理メモリを補完することはできても、物理メモリそのものになることはできない。特にPCの処理速度が遅いと感じるときは、[[CPU]]をより早いものに替えるよりも、物理メモリの容量を見直した方がよい。


*実記憶方式 [#k636a553]

**実記憶方式の種類 [#u438ec92]

***パーティション方式 [#a4d249fc]

 複数のプログラムの同時実行を繰り返す場合には、各プログラムへの領域分割を動的にかつ適切に行うのは難しいので、''パーティション方式(区画方式)''が考えられている。

 パーティション方式は、主記憶装置の記憶領域を複数の''パーティション(区画)''で論理上分割しておく。そして、プログラムはあらかじめどの区画で実行するかを決めておく。ただし、この方式でひとつの区画に収まらないプログラムを実行するにはオーバーレイ方式を併用する。

 パーティション方式には、次の種類がある。

-固定区画方式(単にパーティション方式と言った場合はこちらを指す)
--単一区画方式
---記憶領域にひとつの区画だけ作り、プログラムを割り当てる方式。
---各区画の大きさが固定されているので、区画ごとに未使用領域が散在してしまう。これを''フラグメンテーション(断片化、断片領域)''という。記憶領域の利用効率はよくない。
--多重区画方式
---記憶領域をいくつかの固定長の区画に分け、それぞれのプログラムを割り当てる方式。
---割り当てられる区画よりもプログラムが小さい場合、空き領域ができるため、記憶領域の利用効率はよくない。
-可変区画方式(コンパクションができるので、パーティション方式とは独立にコンパクション方式として分類されることもある)
--プログラムの大きさに応じて区画を割り当てる区画。
--記憶領域の利用効率はよいが、フラグメンテーションが発生することがあるので、これを解消するために周期的にコンパクション((主記憶上のプログラムを再配置して集め、空き領域を連続した領域にして、主記憶上のフラグメンテーションを解消することである。))を行い、各プログラムの主記憶装置の場所を移動する再配置が行われる。この再配置をプログラムのっ実行中に行うことを''動的再配置(dynamic relocation)または動的アドレス変換''という。ただし、動的再配置機構がないシステムでは、フラグメンテーションが発生しやすいため、そのようなシステムでは可変区画方式を採用しない。
---また、プログラムが使用しなくなったメモリ領域や、プログラム間の隙間のメモリ領域を集めて、連続した利用可能なメモリ領域を増やす技術を''ガベージコレクション''という。ガベージコレクションを行わないと、次第に利用可能なメモリが減っていくため、一定期間ごとに再起動が強いられることになる。

[補講]''動的アドレス変換(動的再配置)''は、仮想アドレスから実アドレスへの変換を行うことである。プログラムを読み込む際には動的アドレス変換を行う。仮想記憶方式では、主記憶装置上のアドレスを実アドレス(物理アドレス)、補助記憶装置上のアドレスを仮想アドレス(論理アドレス)という。


***スワッピング方式 [#l751d351]

 ''スワッピング方式''は、プログラムやデータを補助記憶装置に格納しておき、必要に応じて主記憶装置に呼び出したり、補助記憶装置に戻したりする方式である。主記憶装置の記憶領域の空きが少ない場合には、主記憶上で優先度の低いプログラム(プロセス)を補助記憶装置へ移動し、補助記憶装置上で優先度の高いプログラムを主記憶装置に読み込む。

 主記憶に呼び出すことを''スワップイン(ロールイン)''、補助記憶装置に戻すことを''スワップアウト(ロールアウト)''という。

-スワップアウト(ロールアウト)
--優先度の低いプログラムを補助記憶装置に移動すること。
-スワップイン(ロールイン)
--優先度の高いプログラムを主助記憶装置に読み込むこと。

[補講1]スワッピングはプロセス単位、ページングは固定長のページ単位である。

[補講2][[Windows 98]]の場合、Windowsフォルダ内のWin386.swpがスワップファイルになる。その最大サイズはWindowsによって自動的に設定される。[[HDD]]の容量不測などの場合はスワップファイルの最大サイズを調整し、空き容量を確保することも可能である。


***オーバーレイ方式 [#y5dec604]

 ''オーバーレイ方式''とは、プログラムを機能的なまとまりである''セグメント''と呼ばれる単位に分割し、実行時に必要なセグメントだけを補助記憶装置から読み込んで実行する方式である。主記憶装置の容量よりも大きなプログラムを実行する場合に用いられる。

 オーバーレイとは「上書き」を意味する用語である。同じ領域にセグメントを上書きすることからこの名が付いた。

 ここで、必要とするメモリのサイズが主記憶のサイズを越えるプログラムを実行する場合を考える。当然このままではロードできないので、プログラムの構造に注目してセグメントという単位に分割する。セグメントは関数などのプログラムの論理的な構造で分割される。すると、プログラムが[[木]]の構造を持つことがわかる。この木構造の頂点を''ルートセグメント''とし、それ以外のセグメントを''オーバーレイセグメント''という。

例:セグメント分割を行った場合、セグメントAとセグメントBは補助記憶装置に置かれ、必要に応じて主記憶装置へロードされる。

#img(http://security2600.sakura.ne.jp/main2/image2/over.jpg)
セグメントの依存関係
#img(,clear)

#img(http://security2600.sakura.ne.jp/main2/image2/over2.jpg)
主記憶の使い方
#img(,clear)

 セグメント分割が適切でないと、セグメントの入れ替え操作が頻繁に行われ、プログラムの実行効率が悪くなる。したがって、オーバーレイ構造の設計には、十分な経験と実現する応用システムを熟知していることが要求される。


*仮想記憶方式 [#gd6dd389]

 ''仮想記憶方式''は、実装されている主記憶装置の容量よりも大きな論理アドレス空間を提供する仕組みである。プログラムをいくつかに分割し、必要な部分だけを主記憶装置(実記憶空間)におき、必要でない部分は補助記憶装置(仮想記憶空間)におくことによって、大きなプログラムでも実行可能にする。

 プログラムに実際の主記憶容量よりはるかに大きな容量の主記憶(''アドレス空間''と呼ぶ)があるように見せる。つまり、記憶階層の中で主記憶装置と補助記憶装置とをひとつの層(主記憶)に見せかける。このおかげで、プログラマはほとんどメモリの限界を気にせずにプログラムできる。このプログラマから見た広大なアドレス空間を''仮想アドレス(論理アドレス)''と呼ぶ。これに対して実際の主記憶装置のアドレス空間を''実アドレス(物理アドレス)''と呼ぶ。

 プログラムにおけるメモリ参照の局所性を利用して実記憶上にはプログラムやデータの一部が置かれ、対象が実記憶上になり場合に仮想記憶から実記憶へ移される。プログラムは仮想アドレスのみ意識して書かれる。 

 仮想アドレスから実アドレスへの変換は記憶管理機構(MMU)とOSとが協力して行う。

 仮想記憶方式では、仮想アドレスと実アドレスの対応(マッピング)が必要となる。これを''メモリマップ''という。実記憶の対応は主記憶上のテーブルで行われる。

#img(http://security2600.sakura.ne.jp/main2/image3/table.jpg)
#img(,clear)

 メモリマップは仮想記憶方式の種類によって異なる。

-ページング方式
-セグメント方式(セグメンテーション方式)
-ページセグメンテーション方式

 どれが採用されているかはOSによって異なる。例えばWindowsではページング方式が採用されている。


**仮想記憶の目的 [#v1f8b684]

 仮想記憶には次の2つの目的がある。

-複数プログラム間での効率のよいメモリ共有
-主記憶装置の容量不足をフォローする負荷の軽減


***複数プログラム間での効率のよいメモリ共有 [#t96e905c]

 複数のプログラムが実行されている環境では、すべてのプログラムを主記憶にロードすることは不可能な場合が多い。

 例えば、主記憶装置は4ブロック分しか記憶できないとする。このとき、本当はHDDからプログラムAとプログラムBのすべてをロードしたい。しかし、プログラムAは3ブロック分、プログラムBは4ブロック分なので、合計7ブロック分を主記憶装置にロードすることは不可能である。

#img(http://security2600.sakura.ne.jp/main2/image3/hdd1.jpg)
#img(,clear)

 しかし、プログラムのすべてを主記憶装置にロードする必要はなく、ある時点で必要とするのはプログラムの中のほんの一部である。これは時間的局所性から成り立つ事実である。

 そこで必要なブロックだけを主記憶装置にロードすることで、メモリの利用を効率化できる。この方式では、例えばプログラムブロックA1がA2にアクセスする際に、誤ってB1にアクセスしてしまう恐れがある。これをプログラムで検出して回避することも可能である。

#img(http://security2600.sakura.ne.jp/main2/image3/hdd2.jpg)
#img(,clear)

 しかし、仮想記憶を導入すれば各プログラムは自分専用のメモリ空間が与えられたと思い込むことができるので、他のプログラムを意識する必要がない。また、仮想記憶を導入することで、他のプログラムの領域に誤ってアクセスする恐れがなくなる。


***主記憶装置の容量不足をフォローする負荷の軽減 [#bb7680f8]

 単一のプログラムでも、主記憶装置を超える容量のプログラムをロードすることはできない。

#img(http://security2600.sakura.ne.jp/main2/image3/HDD3.jpg)
#img(,clear)

 仮想記憶導入以前は、この問題をプログラム側で対処していた。プログラムを論理的に分割可能な単位(モジュール)に分割し、必要な部分だけを読み込むオーバーレイという方法である。ただし、モジュールを読み込む場合でも、主記憶装置のサイズを越えてロードすることはできない。

#img(http://security2600.sakura.ne.jp/main2/image3/HDD4.jpg)
#img(,clear)

 そのような場合は不要な領域を主記憶装置から追い出して、それから必要な領域をロードする。こうした処理を個々のプログラムで行うとすると、プログラマーの負担が非常に高くなってしまう。

#img(http://security2600.sakura.ne.jp/main2/image3/HDD5.jpg)
#img(,clear)

 そこで仮想記憶を導入することで、プログラマの負荷を仮想記憶が代替してくれるわけだ。


**動的アドレス変換機構 [#r0b8aa9d]

 ''動的アドレス変換機構(Dynamic Address Translator:DAT)''は、論理的なプログラムアドレスを実行可能な物理アドレス(実アドレス)に変換するハードウェアである。

 ページング方式やセグメンテーション方式は、ページ表やセグ面と表に保持された変換情報に基づいて行われる。


**仮想記憶方式の種類 [#gb86e859]

***ページング方式 [#s23d6978]

 ''ページング方式''とは、プログラムを''ページ''と呼ばれる'''固定長'''の単位に分割し、主記憶と補助記憶装置とでページを入れ替えて、主記憶の容量不足を補う方式のことである。実記憶域も同じ大きさのページ枠に分割されている。

 このページの入れ替えを''ページリプレースメント''と呼ぶ。補助記憶装置にページを移動することを''ページアウト''、主記憶にページを読み込むことを''ページイン''という。

 目的とするデータへのアクセスは、ページ番号+オフセット(距離)となる。

#img(http://security2600.sakura.ne.jp/main2/image3/paging10.jpg)
#img(,clear)

 ページを記憶する位置は物理メモリに割り当てられたアドレスによって決定される。物理メモリにプログラムコードやデータファイルを保存するとき、それぞれが記憶している位置はアドレスによって管理される。しかし、保存するプログラムコードやデータファイルが多くなると実際には物理メモリ内に存在しないアドレスが指定されるようになる。

#img(http://security2600.sakura.ne.jp/main2/image3/paging2.jpg)
#img(,clear)

 ページの入れ替えは次の手順で行われる。

1:プログラムをページに分割し、仮想記憶に静的配置する。

2:動的アドレス変換機構によって、仮想アドレスを実アドレスに変換する(動的配置)。

3:主記憶装置上に、必要なページがない場合(ページフォールト)、そのページを主記憶に転送するための割り込みが発生する。

4:主記憶に空きページが十分ある場合は、必要なページを仮想記憶から読み込み(ページイン)、主記憶に空きページがない場合はページを仮想記憶に戻し(ページアウト)してからページインする。

 このような方式が実現可能なのは、プログラム進行のある曲面では、参照されるアドレスがあちこちに飛び回らず、比較的狭い範囲に限定されるという経験則があるからである。このようなプログラムの性質をプログラムの''局所参照性''という。

例:Windowsはページング方式を採用している。

 Windowsのページサイズは4Kバイトになっている。大きなプログラムを4Kバイトのページに切り分け、ページの単位でディスク(仮想記憶)に置いたり、メモリに置いたりする。

 Windowsでは仮想記憶を実現するために、ディスク上に仮想メモリとなるファイル(''ページングファイル''という)を用意する。このファイルはWindowsによって自動的に作成・管理される。ファイルのサイズ、即ち仮想メモリのサイズは、実メモリの同程度〜2倍程度にするのが一般的である。

 Windows 2000で仮想メモリを設定変更するには、マイコンピュータを右クリック>「プロパティ」を選択。「システムのプロパティ」の「詳細」タブ>[パフォーマンスオプション]ボタンをクリックする。 ◇

#img(http://s-akademeia.sakura.ne.jp/main/image9/me.jpg)
#img(,clear)

 ページング方式のメリット・デメリットは次の通りである。

-メリット
--実記憶空間に無駄な領域がなく、ページ単位で管理すればよいので領域管理がしやすい。
--一定の大きさで区切った場合にページ内未使用領域(内部フラグメンテーション)が発生するが、それは実記憶空間の利用効率には影響が少ない。
--ページング方式は実アドレスへの変換処理が単純なため、OSの負荷やコンパイラの生成するコードが単純となる。
--アドレス変換機構が単純になるので、性能もよい。
-デメリット
--必要とする領域が小さい場合でも1ブロックを使用してしまうため、記憶装置の使用効率が悪い。
--ページインとページアウトが頻繁に繰り返されると、そのためにCPUが本来の処理を実行できなくなり、処理効率が落ちることがある。なぜならば、ハードディスクの動作がメモリよりも遅いからである。この処理効率が低下することを''スラッシング''という。
---スラッシングを解消するためには、メモリの増設などによって主記憶装置の記憶容量を増やすか、ページのサイズを小さくするとよい。

 ページング方式では、ページリプレースメントアルゴリズムとして次のいずれかが採用される。

-FIFO方式(先入先出方式)
--主記憶装置上にもっとも以前から存在するページを入れ換える方式。
-LIFO方式(後入先出方式)
--主記憶装置に最後に読み込まれたページを入れ換える方式。
-LRU(Least Recently Used)方式
--主記憶装置上でもっとも長い時間参照されていないページを入れ換える方式。
---最も長時間参照されていないページ(使用後の経過時間が最長のページ)を置き換え対象とする。
---この方式は最近参照されていないページは近い将来にも参照される可能性が小さいという考え方に基づいている。
-LFU(Least Frequently Used)方式
--主記憶装置上でもっとも参照される頻度が少ないページを入れ換える方式。
---最も参照回数が少ないページを置き換えたい対象とする。
---この方式は参照回数の少ないページは近い将来にも参照される可能性が小さいという考え方に基づいている。

[補講]LRUは経過時間、LFUは参照回数と覚えるとよい。

[問題]仮想記憶管理におけるページ置き換えアルゴリズムとして、LRU方式を採用する。参照かつ更新されるページ番号の順番が、「2→3→5→8→2→3→6→2→3→5→1→6」で、実記憶のページ枠が4のとき、ページフォルトに伴なって発生するページアウトは何回あるか?ここで初期で状態では、実記憶にはいずれのページも読み込まれていないとする。 【ソフ開 平成16年度 午前問25】

[解答]ページングの状況を図にすると次のようになる。ただし、数字は参照されたページ番号で、丸の数字はページインされたページ番号とする。

#img(http://security2600.sakura.ne.jp/main2/image3/paging.jpg)
#img(,clear)

 青い線のところがページアウトされたところである。よって、ページアウトは4回行われている。

[補講]ページングとスワップを混同しないように注意。


***セグメント方式(セグメンテーション方式) [#o512deff]

 仮想空間をセグメントと呼ばれる'''可変長'''のアドレス空間で管理する方式。メインルーチン・サブルーチン・データなど意味のある固まりで分割できる。

#img(http://security2600.sakura.ne.jp/main2/image3/seg.jpg)
#img(,clear)

 セグメント方式のメリット・デメリットは次の通りである。

-メリット
--記憶装置の使用効率がよい。
--プロセス間でのプログラムやデータ共有、プログラム実行中のモジュールの取り込み(ダイナミックリンキング)などを容易にできる利点がある。
-デメリット
--長さの異なるセグメントの管理が必要である。
---目的とするデータへのアクセスは、セグメントの先頭アドレス+オフセットを求める。その際に、オフセットがセグメントを指しているかどうかをチェックする必要がある。そのため、アドレス変換機構が複雑である。
--可変長の記憶単位のため、実行していくうちに実記憶空間に未使用料域(フラグメンテーション)が発生して、主記憶の利用効率が低下してしまう。


***ページセグメンテーション方式 [#ce5b66d0]

 ページング方式とセグ面と方式の両方の利点を取り入れた方式である。複数のページをまとめて1セグメントとして扱う。目的のデータへのアクセスはセグメント番号とページ番号と、目的のデータまでの距離という3つの情報を指定することで行う。

#img(http://security2600.sakura.ne.jp/main2/image3/page_seg.jpg)
#img(,clear)


*記憶の階層化 [#la9d4f78]

 現状では、メモリの容量と速度・価格には次のような関係がある。

-小容量
--単価が高い。高速。
-大容量
--単価が安い。低速。

 よって、小容量のものを組み合わせて、処理速度の速いものを作るとコストがかさむ。

 そこで、小容量と大容量、低速と高速のメモリを組み合わせて使用する。これを''記憶の階層化''という。


*メモリリーク [#e5bc29a4]

-[[メモリリーク]]の発生により、PCの性能が低下したり、不安定になったりする。


*ヒープ [#p423f6e4]

 ''ヒープ''とは、OSまたはプログラムによって動的に割り付けられたメモリ領域のことである。ヒープ領域は、プログラムが使う作業領域やプログラムそのものをロードする際に用いられ、必要なくなると解放される。


*メモリとアドレス [#xb49d23d]

 ここでは、話を簡単にするために、16Kバイトのメモリを扱う。16Kバイトのメモリは、1バイトのデータを最高65,536(=216)個のデータを記録できる。1文字は1バイトで表すことができるので、400字詰めの原稿用紙約160枚分にあたる。

 メモリはたくさんあるが、その中の1バイトを指定する方法がなければ、あるひとつのメモリに対して、データを読み書きできない。そこで、メモリには0000H〜FFFFH(0〜65,535)までの番号が順番に割り振られていて、どのメモリでもその番号で直接指定できるようになっている。

[補講]0000H〜FFFFHの「H」は16進数を意味している。

 この番号のことを''アドレス''という。アドレスは0000H番地からFFFFH番地まで常に存在して、そこには1バイトの数値が必ず現れている。


*ROMメモリセルとROMメモリアレイ構造 [#kd31e9cb]

 ROM領域のデータ読み出しは、アドレスデコーダ(アドレス制御回路からの信号を入力して、メモリの列アドレス(ワード線)を選択できるように変換するための復号化回路)を介してROMアドレスに入力する。そして、指定されたROMアドレスのデータは、制御信号作成回路からの制御信号に応じて順次、データバスを介してレジスタへ読み出される。


*メモリの節約 [#a89466b4]

 ディスクを使った[[仮想記憶方式:http://akademeia.info/index.php?CPU%A4%C8%A5%AD%A5%E3%A5%C3%A5%B7%A5%E5#ia39c1cc]]によってメモリ不足でアプリケーションが起動しないということは防げる。しかし仮想記憶によって発生するページインやページアウトは低速なディスクアクセスなので、その期間はアプリケーションの動作が停止してしまう。

 メモリ不足を根本的に解決するためには、実メモリの容量を増えるか、実行するアプリケーションのサイズを小さくする工夫が必要である。アプリケーションのサイズを小さくすれば、それを格納するためのメモリの量を小さくすることができるわけだ。


**DLLファイルで関数を共有する [#u460adba]

 DLLファイルは複数のアプリケーションによって共有される。これによりアプリケーションのサイズが小さくなるので、結果としてメモリ不足を解消させることに繋がる。

 またDLLにはDLLの内容を変更しても、それを参照しているアプリケーションの再コンパイルが不要というメリットもある。


**_stdcall呼び出し [#dddda162]

 _stdcall呼び出しでプログラムのサイズを小さくするという方法は、C言語でアプリケーションが作られているときだけに有効である。といっても他の言語であっても同様の機能があるはずなので、仕組みを覚えておくとよいでしょう。

 C言語では関数を呼び出した後に、スタックのクリーンアップ処理を行う命令を実行する必要がある。スタックのクリーンアップ処理とは関数のパラメータを引き渡すなどに使われるメモリ上のスタックの中から不要となったデータを削除することである。この命令はプログラムの中に記述するのではなく、コンパイル時にコンパイラが自動的に付け加えてくれる。コンパイラのデフォルト設定ではこの処理は関数の呼び出し側に付け加えられる。しかしながら、それではプログラムのサイズが大きってしまう。

 このスタックのクリーンアップ処理を、呼び出された関数側で行うことで、呼び出す側で行う場合よりもプログラム全体のサイズを小さくできる。その際に使用するのが_stdcallである。関数の前に_stdcallを置くことで、スタックのクリーンアップ処理を呼び出された関数側で行うように変更できる。わずか数バイトの節約であるが、何度も呼び出される関数なら効果が出てくる。


*メモリの高速化 [#cbebdade]

-低価格の記憶素子を使用する
--機械全体の処理能力が低下してしまう
-低価格の記憶素子の高速化
--メモリインターリーブ方式
--アドレスインターリーブ方式
--高速バッファメモリ
--連想記憶装置


**メモリインターリーブ方式 [#l23da10c]

 ''メモリインターリーブ(memory interleave)方式''とは、主記憶をいくつかの部分(バンク)に分割して、それらの複数バンクに同時にアクセスできるようにする方式である。簡単にいうと、主記憶装置を増やして同時にアクセスしてしまうということである。RAID0でも採用されている技術である。

 主記憶装置を構成するメモリ素子(主にDRAM)は、バンクの一部のメモリブロックを読み出すだけで、そのバンクの他のメモリブロックの読み出しが一定時間できなくなる。そこで、主記憶装置を、並列動作可能な複数の''メモリバンク(モジュール)''に分割し、順々にアドレスを付ける。ここでは単純に3つのメモリバンクに分けて考えてみる。

#img(http://security2600.sakura.ne.jp/main2/image1/memory.jpg)
#img(,clear)

 アドレスが0,1,2番地と各メモリバンクに付けられていることがポイントである。データは、主記憶装置に連続して記憶されていることが多い。そこで、0番地のデータを読み込むときに、1番地と2番地のデータを同時に読み込むと、3つのデータを1回で読み込むので、アクセス時間を3分の1に短縮できる。

 例えば、0番地から300番地までを連続してアクセスするようなプログラムでは大きな効果がある。しかし、0番地の次に15番地というように、飛び飛びに読む込むプログラムでは効果が出ない。

**アドレスインターリーブ方式 [#d49646b2]

 主記憶をいくつかの部分(バンク)に分割して、アドレスバスを経由してバンクにアクセスする方式である。

**高速バッファメモリ(キャッシュメモリ) [#m1c69cf0]

 主記憶とCPUの間に高速なバッファ(緩衝)メモリを介在させ、主記憶とCPUとの速度差を吸収する方式である。バッファメモリは主記憶装置よりも容量が小さい。


**連想記憶装置 [#g5570f32]

*メモリ領域の特徴 [#e30862fc]

-プログラムのメモリ領域は静的領域・ヒープ領域・スタック領域の3つに分けて管理される。

|領域の種類|静的領域|ヒープ領域|スタック領域|h
|使われ方|アプリケーション開始時に確保される。|開始時に一定領域が確保され、必要の都度アプリケーションに割り当てる。|LIFO|
|格納される情報|グローバル変数、実行コード|任意(アプリケーション依存)|呼び出したサブルーチンの引数、ローカル変数、戻り先(リターンアドレス)|
|確保される単位|アプリケーションでまとめて1つ|システムまたはアプリケーションで1つ|スレッドごとに1つ|

*プログラミング言語とメモリの関係 [#a7bb092f]

**[[OOP]]とメモリの関係 [#jbe04597]

***クラス情報のロード時 [#a772e41c]

-[[クラス情報]]がロードされるメモリの静的領域である。
--しかしJavaでは必要なクラス情報を逐次ロードする方式を採用しているので、実行時にメモリの配置が変化する。よって静的領域ではなく''メソッドエリア''と呼ぶ。

***インスタンス生成時 [#f1d5037f]

-インスタンスが生成されるとそのクラスのインスタンス変数を格納するのに必要な大きさのメモリがヒープ領域に割り当てられる。
--Javaの場合はガベージコレクションの仕組みがあるのでメモリリークも引き起こしにくい。
-このときインスタンスを指定して起動されるOOPのメソッド呼び出しを実現するために、インスタンスからメソッドエリアにあるクラス情報への対応付けも行う。
-インスタンスを指す変数(ポインタが格納される)はヒープ領域にあるとは限らない。
--メソッドの引数やローカル変数ならスタックに置かれ、メソッドエリアにあるクラス情報に配置することもできる。

**従来のプログラミング言語とメモリの関係 [#d6bcc013]

-コードとグローバル変数を静的領域に配置する。
-サブルーチン呼び出しの情報はスタック領域を使って受け渡す。
-ヒープ領域は割り当て処理のオーバーヘッドがかかり、使い終わった後に解放し忘れることでメモリリークも引き起こしやすいためにそれほど積極的に使用されなかった。


*参考文献 [#n87755fb]

-『プログラムはなぜ動くのか』
-『雑学3分間ビジュアル図解シリーズ 電子』
-『その時、パソコンはどう動いているのか』
-『よくわかるマスター CompTIA A+ Core Hardware対策テキスト』
-『MSX POCKET BANK くじけちゃいけない!マシン語入門』
-『図解入門 よくわかるCPUの基本と仕組み』
-『らくらく初級シスアド図解教本 2004春』
-『.com Master ★2004 第7回検定対応』
-『試験対策 要点整理 第2種情報処理』
-『1週間で分かる基本情報技術者集中ゼミ【午前編】 2006春秋』
-『超図解mini 基本情報技術者試験 平成19年度版』
-『平成12年度 【要点・重点】短期集中速攻対策 第1種』
-『ソフトウェア開発技術者 合格エッセンシャルハンドブック』
-『プログラムはなぜ動くのか』
-『実践コンピュータシステム』
-『これならわかる メモリのしくみと活用』
-『ソフトウェア開発技術者 午前対策(基礎編) テキスト』

-『オブジェクト指向でなぜつくるのか』