今回は、トラブル対処の情報2 「メモリ不足」エラーについて
アクセス解析のキーワードに、数件ですが「ACCESS メモリ不足エラー」と言うのがあり、そう言えば昔私も困ったなーと思ったまでは良いのですが、どんな原因で、どんな方法で対処したか。。思い出せません。
1.なぜ「ユーザーが意図せず」発生させてしまうのか(本質)
Access は 小規模データベース向けの簡易ツールでありながら、
・ファイル構造が複雑
・メモリ管理が脆弱
・32bit制限が残っている
・マルチコア非対応の部分がある
・クエリ最適化が自動で行われないという「古い設計」が残っているため、普通の業務運用でも限界を踏みやすいのです。
2.Access のメモリ不足は「あなたのせい」ではなく「Access の仕様」
■あなたが普通に使っていても、Access の内部仕様が原因でメモリ不足を誘発します。
特に 2GB制限・32bit制限・クエリの非効率・ロック膨張・マルチコア問題 が重なると、誰でも再現します。
■64bit版のAccessを採用しても「完全には大丈夫ではない」。
32bit特有のメモリ上限(2GBプロセス制限)は解消されるが、Access 固有の制限(2GBファイル上限・クエリ最適化不足・ロック膨張・マルチコア問題)はそのまま残るため、メモリ不足は依然として発生し得ます。
■64bitにしても「Access の限界」は残る
| 項 目 | 32bit | 64bit |
| プロセスのメモリ上限 | 2GB | 大幅に増加(改善) |
| Accessファイルの2GB制限 | あり | あり(変わらず) |
| ロック数上限(MaxLocksPerFile) | あり | あり(変わらず) |
| マルチコア問題 | あり | あり(変わらず) |
| 大量データクエリの安定性 | 弱い | 改善するが限界あり |
64bit版にすると「32bit特有のメモリ上限」は解消されるが、Access固有の構造的制限は残るため、メモリ不足は依然として起こり得る。
そこで、このキーワードで調査して、大まかですが分類すると下記のようになるのではと思います。
1)マイクロソフトの不具合
2)jetエンジンのヴァージョン
3)メモリリーク、プログラム(VB)コーディング上の問題
4)Accessの仕様
Sponsored Links
1)マイクロソフトの不具合
(1)Access 2007 でクエリを実行するとエラー メッセージ 「メモリ不足です」 または 「クエリが複雑すぎます」 が表示される。
この問題は、Access 2007 に結合の数が 16 までという制限があることにより発生します。また、WHERE 句に大きく複雑なクエリ条件があると、エラー メッセージ「メモリ不足です」 が表示されることがあります。
http://support.microsoft.com/kb/918814/ja
2)jetエンジンのヴァージョンの問題
(1)Microsoft Access の起動時にエラー「メモリ不足のため作業を完了できません」 が表示される。
Access 97 を使用している場合、Microsoft Jet Database Engine 3.5 の更新版3.51をインストールすると改善できます。
http://support.microsoft.com/kb/161255/ja
Accessのバージョンとjetエンジンバージョンの対応表が記載されていますので、必ず参照して下さい。
Jet 4.0 データベースの動作環境を最適に保つ方法
http://support.microsoft.com/kb/303528/
3)メモリリーク、プログラム(VB)コーディング上の問題
(1)Access2000 フォームの開閉を何度も繰り返すとメモリ不足エラーが発生する。
<現象>
Windows 95 または98 上で実行する Access 2000 データベースまたはプロジェクトで、同一セッション中にフォームを何度も繰り返し開いたり閉じたりすると、システムの反応が遅くなり、次のエラー メッセージが表示されることがあります。
不要なアプリケーションを終了し、再度実行してください。
<原因>
Windows 95 または 98 上の Access 2000 でフォームを開いて閉じるたびに、フォント用にシステム GDI リソースが使用され、そのまま解放されません。
ほとんどの場合、このことには気付きません。ところが、24×7 環境などで長期間データベースを開いたままにし、そのデータベースのフォームを何百回も開いたり閉じたりしていると、最終的にパフォーマンスの問題とメモリ不足エラーが発生することがあります。
この現象が発生するまでにフォームを開くことができる回数は、フォームの構造と Windows で他に動作しているプログラムによって異なります。
http://support.microsoft.com/kb/248910/ja
(2)Access 2003 で応答なし、または強制終了する場合がある。
Access 2003、 IME 2003 または、Access 2002、 IME 2002 を使用しているとメモリ リークが発生し、Access が、応答なし、または強制終了する現象。
http://support.microsoft.com/kb/884086/ja
(3)98系のOSで、VBエディタを開くときにメモリ不足エラーになる。
98系のOSはすぐにリソースが無くなりますので注意です。(不要なソフトは全部落として使用する)
(4)VBでファイルを操作するコーディングで、最後にファイルの解放処理記述が抜けている為に、メモリ不足になる。
Rst.Close、 Set Rst = Nothing等を記述しないと、メモリリークを起こす可能性があります。
<補足>
■mdbの編集作業での注意事項
mdbは、開発中に頻繁に修正すると肥大化しますので、「最適化」処理をたまに実施しながら編集しましょう。
■mdbが、何かの拍子?で壊れることがあります。
なおらない場合には、新規mdbファイルに全てのオブジェクトを移すと、なおる可能性があります。
私などは、この方法で何度も救われています。
98時代は、よくありましたが、XPになってから減ったように思います。
開発環境も、98の時代はマシンの性能やOSの能力が、余りにも貧弱だったのだと思います。
(5)クエリーを使って検索する場合、Null値などの扱い方によては、メモリ不足になる場合があるようです。
・https://blog.goo.ne.jp/itachi-yang/e/08f8919673e7b84615caf449133ed071
・https://answers.microsoft.com/ja-jp/office/forum/office_2010-access/access2010/c3a25645-5c2c-4448-aeb6-9725a86f1fbe
4)Access の仕様
Microsoft社のサイトに「Accessの仕様」と云うページがあります。
Microsoft Access データベース ファイルおよびオブジェクトの制限に関する情報が含まれています。 データベースがこれらの制限を超えるということは、多くの場合、設計に問題があることを示しています。
(1)Access ファイルの 2GB 制限を超えやすい構造
Access は データ・フォーム・レポート・クエリ・VBA すべてを1ファイルに保存します。
そのため、データ量が増えていなくても、更新・削除を繰り返すだけで内部に「見えないゴミ」が溜まり、実ファイルが膨張して 2GB に近づくとメモリ不足が発生します。
(2)32bit Office のメモリ上限(最大2GB)
PCに16GB積んでいても、32bit版 Office は最大2GBしか使えません。
Access は複雑なクエリやJOINを実行すると一気にメモリを消費するため、すぐに上限に達します。
(3)巨大テーブルに対するクエリ・更新処理でロックが膨張する
大量レコードに対してアクションクエリを実行すると、ページロック数が MaxLocksPerFile(既定9500)を超えることでメモリ不足が発生します。
(4)Access エンジンがマルチコアCPUと相性が悪い
Access のデータベースエンジンはマルチスレッド前提で設計されていないため、 マルチコア環境で逆にメモリ不足やフリーズが起きることがあります。 CPU を1コアに固定すると改善するケースが報告されています。
(5)クエリの書き方がメモリを爆発的に消費する
特に以下はメモリ不足の温床です:
- DLookup を大量に使う
- NULL許容フィールドに対して比較演算子を使う
- 巨大テーブル同士の複雑なJOIN
- インデックス未設定の検索
(6)Access がメモリを解放しないバグ的挙動
連続した Insert/Update/Delete を行うと、メモリバッファが解放されず蓄積し、メモリ不足が発生することがあります。 WorkingSetSleep レジストリ設定で改善するケースがあります。
3.何をした時に 一番多く メモリ不足のエラーになるのか?
Access で最も多く「メモリ不足」エラーが発生する操作は、
①大量レコードの連続 Insert/Update/Delete
「連続したレコード追加・更新・削除を繰り返すとメモリ不足が発生する」 と明記されています。
原因は以下の2つ:
・ページロックが膨張し MaxLocksPerFile を超える。
・Access エンジンがメモリを解放しない(メモリリーク的挙動)。
特にバッチ処理やループでの更新は最も危険です。
②巨大テーブルへのアクションクエリ実行
巨大テーブルに対するアクションクエリ(UPDATE / DELETE / INSERT)。
Microsoft Learn でも、 「大きなテーブルにアクションクエリを実行するとメモリ不足が発生する」 と記載
理由:
・トランザクションのロック数が既定値(9500)を超える。
・ロールバック用のメモリ確保ができなくなる。
③複雑クエリの実行
複雑な SELECT クエリ(JOIN多用・NULL比較・DLookup多用)
複雑クエリ実行時に「システムリソースの超過(メモリ不足)」が発生することが公式に記載。
また、技術ブログでは以下の条件で頻発すると報告:
・NULL許容フィールドに比較演算子を使う
・DLookup を大量に使う
・巨大テーブル同士のJOIN
④ファイル肥大化(2GB接近)時の処理
Accessファイルが2GBに近づいた状態での通常操作
一般ブログでも、 「クエリやマクロ使用時にファイルが2GBに近づくとメモリ不足が出る」 と明記。
これは実メモリではなく Accessファイルの2GB上限 が原因。
⑤マルチコアCPU環境でのクエリ実行(Accessエンジンの非対応)
Accessエンジンはマルチスレッド前提で設計されておらず、 複数コアで動作するとメモリ不足が発生する と技術ブログで報告。
ここに記載されている各「属性」が、最大値を超えていないか、確認する必要があります。
Microsoft社のサイト2つ
■Accessの仕様
■Access のパフォーマンスを向上させる
4.Access のメモリ不足は「実メモリ不足」ではない
Access のメモリ不足エラーは、実際には以下のどれかが原因です:
・2GBファイル上限に近づく
・ロック数(MaxLocksPerFile)超過
・クエリのメモリ消費が爆発
・Access エンジンがメモリを解放しない
・マルチコアCPUで不安定化
つまり、PCのメモリが16GBあっても関係ないというのがポイント。
—関連記事—
・Access 2019 の新機能について
・マイクロソフト、「Access」の便利な機能を使って、業務アプリケーションを作成して活用する。
・Access 2013 の新機能とAccess 2013 で廃止、変更された機能とバージョンアップの必要性について
・第1回 ACCESS(アクセス)データベース作成ソフトについて
・第2回 ACCESS(アクセス)データベース作成ソフトについて
・第3回 ACCESS 2007の情報
・第4回 ACCESS トラブル対処の情報1「mdbが壊れてしまった時」
・第5回 ACCESSを「ファイル共有」で使用する場合の注意事項
・第6回 ACCESS トラブル対処の情報2 「メモリ不足」エラーについて
・第7回 ACCESSで Jet 4.0 データベースの動作環境を最適に保つ方法
・第8回 Access 2000とMSDEを利用してクライアント/サーバーシステムを構築する
・第9回 ACCESS 2010の情報
・第10回 Access2000(mdb)からAccess2010(accdb)に変換する
Sponsored Links
コメント