動的メモリの上限について – プログラミング – Home

動的メモリの上限について
 
通知
すべてクリア

[解決済] 動的メモリの上限について

固定ページ 1 / 3

大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

くだらない質問かも知れませんが教えて頂きたいです。

CArrayやCStringなどで宣言すると動的にエリアを確保すると思いますが、
その上限はどのぐらいまで有効なのでしょうか?
環境や、PCのメモリサイズにもよると思いますが・・・
3Mぐらいは余裕ですかね?


引用未解決
トピックタグ
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

別のスレッドで話題になった事があったと思いますけれど、
通常、一つのプロセスは2GBがメモリアクセスができる上限だったともいます。
但し、実際にヒープ領域として使用できるのはそこまで大きな領域には
ならないはずです。プログラムやOSが動作する為に使用する領域も2GBに含まれて
いたと思います。
実際にはPCの搭載しているメモリの量に寄りますね。
実際にはスワップファイルを用いて実搭載している物理メモリ以上の容量が
使えますけれど、スワップが発生するとパフォーマンスが急激に落ちますので
実際にはスワップが発生しない程度に抑えないと使い辛いソフトになると思います。
この辺は必要動作環境をどの程度に設定するかと言うアプリの設計にも寄ります。
考え所でしょう。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ああ、前提条件を忘れてました。
Win32の環境であればと言う但し書きがつきます。
Win64だともっと大容量のメモリが扱えるようになります。
この辺はご自分で調べて見てください。
Webを検索するれば、結構引っかかると思います。


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

内容が不十分のため、補足します。

何がやりたいのかというと、

typedef struct{
15byte
}; KATA

15バイトのデータを持つ情報が最大16000の配列分ある。
CArray<KATA,KATA>m_def;
WORD m_defNum; // 最大16000ぐらい

このなかである条件を満たした情報のインデックスを次のm_1に保存していく。
m_1の情報の中でさらに、
ある条件を満たすもののm_defのインデックスをm_2に保存していく。
これを最大m_5まで行なう。

CArray<WORD,WORD>m_1; // m_defのインデックス
CArray<WORD,WORD>m_2;
CArray<WORD,WORD>m_3;
CArray<WORD,WORD>m_4;
CArray<WORD,WORD>m_5;

しかし、もしメモリが余裕ならば、
CArray<KATA,KATA>m_1;
CArray<KATA,KATA>m_2;
CArray<KATA,KATA>m_3;
CArray<KATA,KATA>m_4;
CArray<KATA,KATA>m_5;
このようにそれぞれで情報をもったほうが
メモリは無駄になるが、
処理が早くなる。
判定など必要なくなる。
なので、
できれば後者のほうがいいと思うのですが
どうでしょうか?


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

計算すると、
m_defの情報全てが条件に満たしたとして(m_1~m_5)
前者だと1.44Mで後者は400Kになりました。
そのほかにも動的に確保しているものもあるので、
多くみつもっても3Mぐらい使用するかな?ということです。

最近のPCはほとんど512M以上のメモリがあると思うので
このぐらいのサイズなら余裕かな?
と、思うのですがいかがなものでしょうか?
みなさんの見解を聞きたいです。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

m_1、m_2、m_3、m_4、m_5に重複した物が入らないのであれば
最初にデータを振り分けてしまえば最初のm_defはいらないのではとも思いますが、
多分、私ならやりません。
データの二重管理になるので両方の整合性とかメモリの無駄とか考えたら
あまり良い方法とは思えないからです。
また、インデックスを保持する方法でもそこまで遅くなるとは思えないんですが、
実際に実験してみましたか?
その差は無視できないほど大きな差になったでしょうか?

CArrayはリリース版とデバッグ版では全くスピードが違いますから
パフォーマンスを見るのでしたらリリース版で確認しないと駄目ですよ。


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

>m_1、m_2、m_3、m_4、m_5に重複した物が入らないのであれば
>最初にデータを振り分けてしまえば最初のm_defはいらないのではとも思いますが
m_defの内容は必要です。
m_defの内容の中で検索条件Aにひっかかるものをm_1に登録。
m_1の内容の中で検索条件Bにひっかかるものをm_2に登録。
そのときの検索内容をリストコントロールに書き込みます。(検索前はm_defの内容全て)
また、デフォルトボタン押下時は、m_1~m_5の内容は削除します。(RemoveAll)
検索条件のトリガは5つほどあるので重複することは普通にあります。
また、m_3→m_2と戻ることはありません。
別の検索方法で内容を絞りたいときは【デフォルト】ボタンを押します。
また、検索条件はアプリ実行者が選択するものであらかじめ決まっているもの
ではありません。

>また、インデックスを保持する方法でもそこまで遅くなるとは思えないんですが、
>実際に実験してみましたか?
してないです。
その部分はこれからコーティングするんですけど、
インデックスを保持する方法よりそれぞれデータ保持するほうが
プログラム的にも判定が少なく美しいと思ったからです。


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

今思いついたのですが、
CArray<KATA,KATA>m_def;
CArray<WORD,WORD>m_1;
の型が異なるために余計な判定や
設計に苦労してます。

よって、
CArray<WORD,WORD>m_0;
というのを宣言しておいて
m_defの要素に追加する時に同時に
同じインデックスを初めから設定しておけば
型が同じになるので設計も楽になります。
領域が無駄にひとつ増えますが、
こんなことで悩むぐらいならいいかと・・

自分としてはメモリ領域に余裕があるなら
無駄な領域を確保しても
それでプログラムが美しく、
設計しやすくなるなら
そのほうがよいと考えています。

どうでしょうか?


返信引用
ねこたま
 ねこたま
(@ねこたま)
ゲスト
結合: 19年前
投稿: 8
 

美しいとかはとりあえず置いておいて、何がしたいのかよくわからないとこですが、
CArrayの使いかたからしてどう問題なのかな?と

ちなみに私はインデックス保持派っすね
やっぱ同じデータを複数作成するってのはどうも。。。

で、そうすると参照時は
for(int i=0;i<m_1.GetCount();i++){
hoge = m_def[m_1[i]].m_hoge;
}
ですよね?

インデックス登録時も同様な感じで
for(int i=0;i<m_def.GetCount();i++){
// いろいろ判定
m_0.Add(i);
}
でいいですよね?
どこにどういった問題が?


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

>m_def[m_1[i]].m_hoge
こういう参照の仕方ができるんですね?
しりませんでした。
C言語のポインタと同様な感じですね(^_^)

>ちなみに私はインデックス保持派っすね
俺もそうです。
そのつもりで作ってます。
1つ前の発言のように
CArray<WORD,WORD>m_0;を登録しておく方法がよいってことですか?


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

実データがm_defで、m_1~m_5は、その部分集合ですよね?

CArray<KATA> m_def;
CArray<KATA*> m_1, m_2, m_3, m_4, m_5;

私ならまず、↑のようにすると思います。
速度もメモリ消費量も気にするほどのことではなさそう、
という予想で、プログラムの作りやすさを優先します。

> CArray<WORD,WORD>m_0;を登録しておく方法がよいってことですか?

m_0には、WORD型で、0, 1, 2, 3, ... , というデータが入るのならば、
何の意味もないと思いますが。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

> 今思いついたのですが、
> CArray<KATA,KATA>m_def;
> CArray<WORD,WORD>m_1;
> の型が異なるために余計な判定や
> 設計に苦労してます。

この設計でなぜ大変になるのか良くわからないです。
m_1に入るのはインデックスですからそんなに面倒とも思えません。
CArrayのインデックスの型にあわせたいのであれば、
CArray<int, int> m_1;とすれば済む事ですし。
使い方にしてもねこたまさんの書き込みを見れば、
対して面倒でもない事が直ぐわかります。

通常、データの二重管理はデータの整合性が狂う可能性を考えると
真っ先に避けて考える方法だと思います。
ましてや今回の話の内容からすると最大で同じデータを5重に持つことすらありえそうです。
もっとも、参照だけであれば重複して持ったとしても致命的なバグにはならなそうですが。

あと、使わなくてもパフォーマンスも出るし、そこまで複雑な作りになるわけでもないの
であれば、
メモリは極力最小限に留めるべきではと私は思います。
Windowsは自分が作ったアプリ以外のアプリも同時動いている可能性があるわけですし、
出来る限り無駄は省くべきでしょう。
メモリ使用量を減らそうとするあまり不必要に複雑化するのはよくないと思いますが、
今回の件はそこまで複雑になっているとは思えません。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

> CArray<WORD,WORD>m_0;を登録しておく方法がよいってことですか?

これは必要ないと思います。
というか、これを何に使うのでしょう?
ねこたまさんの書き方が出来る時点で必要ないと思いますけれど。
なぜ、必要なのかが理解できないです。


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

>実データがm_defで、m_1~m_5は、その部分集合ですよね?
そうです。

>私ならまず、↑のようにすると思います。
以前はそのように考えていました。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200606/06060056.txt

>通常、データの二重管理はデータの整合性が狂う可能性を考えると
>真っ先に避けて考える方法だと思います。
そのように考えています。
PATIOさんの言ってることは全て正しいと思うし、
自分もいつもその考えで設計しています。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

インデックスで管理しないのであれば、たいちうさんが書いているような
ポインタで参照できるようにする方法もありでしょうね。

あと、15バイトで16000件最大なら240KB程度の話なので
クラスメンバー上は単純に

KATA* m_pDef;

とでもしておいて
クラスのコンストラクタでm_pDef = new KATA[16000];として確保しておいて

CArray<KATA*> m_1, m_2, m_3, m_4, m_5;
としてポインタの配列にしておけば、直接参照可能ですね。

ちなみにですが、CArrayの各要素のポインタって取れましたっけ?
CArrayのソースを見ればわかるかもしれませんけれど。


返信引用
固定ページ 1 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました