
Excel VBAでは大きな配列を生成しようとすると
メモリ不足でエラーが出るため、
どの程度のサイズまで作れるか試してみました。
Dim aaa() as Single
ReDim aaa(xxxxx)
というようにして定義しています。
Singleの配列を一つの場合には、
132813299
が上限であることが分かりました。
Singleの配列を2つの場合には、
132813299
130009804
が上限となりました。
Singleの配列を3つの場合には、
132813299
130009804
9
が上限となりました。
なぜか3つめは9より大きな配列を作ることができません。
それで配列サイズを小さくして試してみたところ
60000000
60000000
60000000
60000000
60000000
32000000
のようにして、3つの場合の合計よりも
大きなメモリを確保することができました。
つまり、合計のサイズに上限が決められているわけでもなく
配列一つ一つのサイズに上限が決められているわけでもないということが分かりました。
一体どういう法則でメモリサイズの上限が決定しているのでしょうか?
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
まず配列があるプログラム共通ですが、絶対的な配列の限界としてaaa(xxxxx)のxxxxxに限界があります
xxxxxはプログラム上変数として扱われており、変数が扱える数の限界が存在します
その限界が"132813299"だと思われます
変数の限界に関してはVBAならIntegerやLongなどを調べると記載されていますが、元から変数としての最大値が決定されているため、メモリにどれだけ余裕があろうとそれ以上取る事はできません
そのため配列を増やすと変数の上限は回避できます
ここからは完全に予測なりますが、前述のとおり配列の数を表すのにも変数が使われております
そして変数は型を宣言した時点で、通常はメモリが確保されています
特に動的配列は配列の数を変更する度に、使用するメモリサイズを宣言しなおしているため、動的配列として扱えてます
ここで問題となるのは事前に確保されるメモリの話で10個程度の配列を表すのに、"132813299"の数を表せる変数を使うのはメモリの無駄です
ですから無駄を避けるためには、小さ目の型でメモリを確保して置き、後から必要となった際に大きな型に変更する処理を行っていると思われます
この結果、配列の数を表す変数に大きくメモリサイズが消費されていない細かく分割した3番目のケースが最も効率よく配列を多く取れたとしても不自然ではありません
配列の大きさで変わる原因としては以上が考えられます
最もシステムのメモリ使用状態が同一であると仮定した上での話ですから、複数回試さないと確実とは言えません

No.2
- 回答日時:
それはExcelというアプリケーションの構造に由来する話になるでしょう。
まず、どういった確保方法であれ、Windowsの32ビットアプリケーションで使用できるメモリの最大量(2GB)が絶対の上限として存在します。この2GBの中でVBAとExcel本体が使用するメモリの両方をやりくりするので、VBAが使用できる量は当然ながらもっと少なくなります。
またExcel本体側のメモリ使用状況によっては、空きメモリ領域が複数に分断されているかも知れません。例えばVBA側にメモリを1GB渡せるとしても、それは1つの固まりではなく、128MBや64MBなどの断片をかき集めたものかも知れないと言うことです。メモリの使用状況は予測が難しいため、最初から断片になることを見越して、あまり連続するメモリを取れなくしてある可能性も十分にありえます。配列は連続するメモリ領域に収まる分しか確保できないため、これが配列を小さくした方が、トータルではより多い配列を確保できる理由として考えられる点です。
メモリ使用状況起因だとすると、今出ている数値はどのPCでもそうなるとは限らないし、もしかすると今のそのPCでも毎回そうなる保証がないということになります。
No.1
- 回答日時:
先に断っておきますが、私はVBAについての見識はほとんどありません。
ですのでうそ情報かもしれないことを念頭にお聞きください。
あくまでプログラム全般の法則として回答します。
まずさきに質問の答えとしては、
「合計のサイズに上限が決められている」だと思われます。
プログラムのメモリ確保にはスタックとヒープからの二種類の確保があります。
スタックから確保されるのは、関数のなかのローカル変数のメモリ割り当てになります。
今回のReDimの場合は、おそらくヒープからメモリ確保されているように思います。
ヒープからのメモリ確保というのは、ヒープというある程度大きいメモリから要求されたサイズの
メモリを割り当てることです。
今回のケースでの確保できる最大値というのは単純にヒープのサイズに依存するということです。
ですが、ヒープとは他からもメモリを確保されるため、
すでに使用されている分だけ確保できるメモリサイズは小さくなります。
また、メモリの確保と開放(ReDimでサイズを変えたり、不要なオブジェクトにnullを代入したり等)を行うことで
ヒープは分断化され確保できるメモリの最大値が変わってきます。
(おつかいのVBAのバージョンによっては、可能な限り確保する努力をしてくれるはずですが)
ヒープのサイズに関してですが、こちらはPCの環境(エクセルのバージョンやPCのスペック)に
依存するかと思いますので、ご自身のPCでメモリ確保できたものが、
別のPCではメモリを確保できないなどの現象もあるかもしれません。
不用意に巨大なメモリ確保を行うようなマクロは控えたほうがいいと思います。
ちなみに132813299の値を調べる際どのようなコードで調べられたでしょうか?
下記のようにループで検証した場合、ReDimの仕様上(新しいメモリへデータをコピーする可能性もある)
ヒープ上に以前の確保したメモリと、
これから新規に確保しようとしたメモリの二つが存在する可能性があり、
単純に最大サイズを検証することはできないと思います。
i = 1
Do
i = i + 1
ReDim aaa(i)
While
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
エクセルVBA 配列からセルに「関数式」を一気代入したい
Visual Basic(VBA)
-
vbaのエラー対応(実行時エラー7:メモリが不足しています)
Visual Basic(VBA)
-
配列をEraseしてもメモリが開放されていない?
Visual Basic(VBA)
-
-
4
Excelのメモリ(配列)の上限は2Gではないのか
Excel(エクセル)
-
5
エクセルVBA コードが同じでもファイルによって処理速度が大きく変わるのはなぜ
Visual Basic(VBA)
-
6
worksheetFunctionクラスのVlookupプロパティを取得できません エラーへの対応
Visual Basic(VBA)
-
7
array関数で格納した配列の型を変更する
Visual Basic(VBA)
-
8
VBA シートをコピーする際に Copyメソッドは失敗しましたのエラーが出てしまいます
Visual Basic(VBA)
-
9
VBA 1次元配列を2次元に追加する
Visual Basic(VBA)
-
10
VBAを何回も作り直して、容量が増えた
Excel(エクセル)
-
11
メモリが不足しています(VBA)
Visual Basic(VBA)
-
12
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
13
VBA public変数はどのようなことをしたら解放されますか?
Visual Basic(VBA)
-
14
EXCELのVBAで作業ファイルを閉じてもメモリの解放をしなくて困っています
Excel(エクセル)
-
15
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
16
配列の中の最大値とそのインデックス番号を取得する方法
Visual Basic(VBA)
-
17
IF関数で空欄(")の時、Nullにしたい
その他(Microsoft Office)
-
18
Excelのセルの色指定をVBAから配列を用いて効率的に行う方法はあり
Visual Basic(VBA)
-
19
Application.ScreenUpdating = Falseが効きません
Visual Basic(VBA)
-
20
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
メモリが不足しています(VBA)
-
メモリを解放しないとどうなる?
-
メモリのセグメント違反の解決...
-
エクセルのメモリ使用状況/Appl...
-
非再入可能なプログラム
-
PIC 文字 を 数値に 変換
-
メモリ不足
-
Bitmapを重ね合わせる方法
-
移動可能メモリ
-
直接メモリにアドレス割付けで...
-
クリスタルレポートでメモリ不...
-
大容量のメモリ確保をスワップ...
-
「ヒープサイズの設定」て何?
-
エラー処理,メモリ開放,exit
-
C言語における再帰呼び出しの...
-
EXCEL-VBAにてADOのレコードセ...
-
H8について教えて下さい。
-
C言語初心者です。debug assert...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語で、メモリを解放しないで...
-
Access Violationについて
-
VBAの配列サイズとメモリに関して
-
メモリのセグメント違反の解決...
-
メモリが不足しています(VBA)
-
メモリ不足
-
大容量のメモリ確保をスワップ...
-
ファイルマッピング関数で失敗
-
PC-98で拡張メモリを使え...
-
エラーについて
-
「ヒープサイズの設定」て何?
-
エクセルのメモリ使用状況/Appl...
-
C言語における再帰呼び出しの...
-
オフスクリーンサーフェスへの...
-
1ページに収まるオブジェクト...
-
新規購入PCのスペックについて...
-
4GB搭載したマシンのメモリ情...
-
組み込み系でのmallocについて
-
ルネサスマイコン(R8C) ビルド...
-
Visual Basic Net2003
おすすめ情報