- PR -

コンソールアプリとDLLのメモリの管理の違いについて

投稿者投稿内容
ぽち
常連さん
会議室デビュー日: 2006/05/31
投稿数: 21
投稿日時: 2006-11-27 15:33
お世話になります。
VC.net2003でコンソールアプリを作成し
#define N 10000
double A[N*N];
と記載してコンパイル実行すると正常に動作します。

それを.netのクラスライブラリ及びMFC DLLでプロジェクトを作成し同様に記載して
VB.netから呼んだ場合
「'System.DllNotFoundException' のハンドルされていない例外が Project1.exe で発生しました。」と例外を発生して終了します。
#define N 8000に減らした場合、エラーを発せず動作します。

メモリ的にかなり厳しいことは承知していますがコンソールアプリで実行できたものが
DLLにすると動作にないのは腑に落ちません。

最終的にはコンソールアプリのソースをDLL化してVB.netから扱えるようにしたいと考えています。

このような事象に心当たりの方がいらっしゃいましたら教示ください。

Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2006-11-27 15:38
スタックにとらないでヒープで領域をとるのはどうでしょうか?

コード:

double* A = new double[ N * N ];



delete[] A;



[ メッセージ編集済み 編集者: Blue 編集日時 2006-11-27 15:39 ]
Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2006-11-27 15:49
MSDNフォーラムで似たような質問がありました。
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=570699&SiteID=7
ぽち
常連さん
会議室デビュー日: 2006/05/31
投稿数: 21
投稿日時: 2006-11-27 19:04
ありがとうございます。

Thread コンストラクタ (ThreadStart, Int32)
メモ : このコンストラクタは、.NET Framework version 2.0 で新しく追加されたものです。
とのことで.net2003ではコンパイルが通りませんでした;;

double* A = new double[ N * N ];
realloc、mallocなどでも定義してみたのですがステップインすると<未定義の値>
で領域を確保できずぬるぽが返ってきました。
なお領域を少なくするとポインター値がステップインで確認できました。

巨大配列を作って外部のライブラリにそのまま
投入しなければならない為ほとほと困り果てております。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-11-27 19:42
引用:

巨大配列を作って外部のライブラリにそのまま
投入しなければならない為ほとほと困り果てております。



そうは言っても 8 * 10000 * 10000 = 800MB 弱ですよね?
64bit OS にでもしない限り、リニアに確保するのはなかなか厳しいセンだと思いますよ。

どうしてもってことなら、Server OS で /3GB でもつけてみるとか。。。
(↑XP でも有効という情報がありますが、ウチではまともに動いた実績がありません)

あと、IME とか、日本語サポートを完全に外した状態で実行すると少し余裕が出るかもしれません。


[ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2006-11-27 20:00 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-11-28 08:47
引用:

ぽちさんの書き込み (2006-11-27 19:04) より:
巨大配列を作って外部のライブラリにそのまま
投入しなければならない為ほとほと困り果てております。


この仕様を見直す事が出来るのなら、見直したほうが良い。他の方も言っている様に、800MB近い連続したメモリを確保するのは困難です。以前コンソールアプリのときに確保できたのは、メモリを実際に確保するタイミングの違いでしょう。アプリケーション実効直後だったので、連続したメモリ領域を確保しやすかったのかと・・・。DLLだとメモリを確保するタイミングが後にずれますからね。

どうしても800MBの領域を必要としているのであれば、その部分を別プロセスに分離する事で動作しやすくなると思います。全ての操作をその別プロセスに対するプロセス間通信で行うので、パフォーマンス的には大きなマイナスになるでしょう。
_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
ぽち
常連さん
会議室デビュー日: 2006/05/31
投稿数: 21
投稿日時: 2006-11-28 15:05
お世話になります。
一縷の望みを託してVS2005の試用版をインストールしてみました。
Dim t As New Thread(AddressOf CLAStart, (8000 * 8000 * + 1000)
t.Start()

t.Start()の時点で
種類 'System.OutOfMemoryException' の例外がスローされました。で落ちました;;
MSDNフォーラムの人は何で通ったんでしょう・・
8000*8000でも駄目になったのはPCが変わったためです。

仕様も見直せればいいのですがライブラリを使用している部分を自前で実装して
なおかつライブラリのパフォーマンスと同等まで上げるのは私には限りなく無理です。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-11-28 15:42
引用:

仕様も見直せればいいのですがライブラリを使用している部分を自前で実装して
なおかつライブラリのパフォーマンスと同等まで上げるのは私には限りなく無理です。



と言ってみたところで、物理的に無理なものは無理ですよ。

32bit Windows で利用可能なアドレス空間は 4GB しかなく、そのうちユーザエリアは 2GB で、そこに各種 DLL とシステムプログラムが読み込まれて実行されるわけなので、1GB 近くのリニアなメモリを必要とするのは、設計どころか構想段階でNGなのです。

ということで、早々に別な解決策を探すのが吉と思います。

スキルアップ/キャリアアップ(JOB@IT)