C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[15]: Global.asax における静的共有変数の取り扱い [1]


(過去ログ 129 を表示中)

[トピック内 23 記事 (21 - 23 表示)]  << 0 | 1 >>

■76481 / inTopicNo.21)  Re[13]: Global.asax における静的共有変数の取り扱い
  
□投稿者/ なちゃ (55回)-(2015/07/13(Mon) 20:53:56)
No76480 (なちゃ さん) に返信
> 開発サーバでエラーが起きたのは、32ビットで動いていたからでしょうね。

ちょっと調べてみたところ、開発WebサーバはLARGEADDRESSAWAREフラグはついていないようです。
ということは、64OS上でもユーザメモリ空間は2GBまでしか使えないという事になります。
この場合、1GBの確保は無理な可能性が高いですね。

一方、IISのワーカープロセスは、32ビットモードでホストした場合でもLARGEADDRESSAWAREが有効になっていますので、64OSではユーザメモリ空間は4GBまで利用可能です。
そのため、1GB確保でも案外動いてしまうかもしれません。

この辺りでも挙動が変わってくる原因になります。
解決済み
引用返信 編集キー/
■76483 / inTopicNo.22)  Re[14]: Global.asax における静的共有変数の取り扱い
□投稿者/ なちゃ (57回)-(2015/07/14(Tue) 02:57:04)
ついでに文字列作成操作に絡むメモリの利用のされ方について。

StringBuilderで文字列を作成するとき、CLRの2までは、必要なバッファをそのまま連続メモリ領域として確保していました。
またStringBuilderは容量が不足すると、領域を倍のサイズで確保しなおします。
ということは、1GBの文字列を作成しようとした場合、最悪2GB近い連続領域が確保されるということです。
またその時には元の1GB近い領域も同時に確保した状態ですから、3GBもの連続領域(1GB+2GB)が一時的に必要になります。
また、最後にToStringした際、最悪では2GB近い領域がそのまま文字列に転用されます。
1GBは無駄になるわけです。
また、連続メモリ領域ですので、LOHにも大きな負担がかかります。

CLR4以降では、StringBuilderは、内部バッファを小さいメモ例領域として分割確保するようになりました。
これにより、連続メモリ領域確保による、LOHへの負担はなくなりました。
ただし、ToStringで文字列に変換する時点では文字列バッファの再確保とコピーが必要になるため、やっぱり一時的には最悪で文字列に必要な容量の3倍のメモリ領域が確保されることになります。
とはいえ、連続領域は必要最低限の量だけですので、CLR2と比較すると、LOHへの負担ははるかに小さくなります。
ただし、ToStringで必ずバッファの再確保とコピーが発生するため、ToString自体にかかる時間はCLR2よりも長くなる傾向があります。

今回の例ですと、1GBの文字列を作成するために、実際には3GBの領域が必要になってしまっているかもしれません。
もし最初から文字列の長さが分かっているなら、StringBuilderのキャパシティを明示設定することで、無駄を減らすことはできます。
ただ、CLR4の場合は、それでも一時的に2GBの領域が必要になりますが。
CLR2だとうまくやれば1GBで済むため、場合によっては.NET Framework 3.5などの方が有利なこともあるわけですね。

解決済み
引用返信 編集キー/
■76484 / inTopicNo.23)  Re[15]: Global.asax における静的共有変数の取り扱い
□投稿者/ なちゃ (58回)-(2015/07/14(Tue) 10:27:19)
> 今回の例ですと、1GBの文字列を作成するために、実際には3GBの領域が必要になってしまっているかもしれません。
> もし最初から文字列の長さが分かっているなら、StringBuilderのキャパシティを明示設定することで、無駄を減らすことはできます。
> ただ、CLR4の場合は、それでも一時的に2GBの領域が必要になりますが。
> CLR2だとうまくやれば1GBで済むため、場合によっては.NET Framework 3.5などの方が有利なこともあるわけですね。

すみません、一つ訂正です。
CLR4ではチャンク分割したバッファを使用するので、当たり前ですがもはや現在の容量の2倍といった確保の仕方ではなくなってますね。
なので、無駄な容量の確保はほとんど発生しません。
またバッファ確保の負荷は仕組みからいって遙かに小さくなっているはずなので、キャパシティを指定する必要性もほぼなくなっていると思われます。

何も考えずに普通に使っても、一時的に文字列容量の倍のメモリ領域を使うだけですむはずですね。
今回の1GBだと、2GB程度のメモリ使用量ですむはずです。
解決済み
引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -