10570


UnityのC#でコードを組んでいて疑問に思ったことなのですが、  
構造体はスタック領域を使うと書いてあるのですが、  
Listに関しては記述がなく、値型でない限りは参照型になるので  
ヒープ領域を使うと思っています。

### 質問

  1. List<構造体>とした時は、どちらにメモリが確保されるのでしょうか？
  2. また、スタックに確保されたか？ヒープに確保されたか？を知る方法はないでしょうか？

### 経緯

UnityのC#ではヒープ領域がガベージコレクションで解放されないため、  
１度ヒープ領域が更新されるとアプリを落とすまでヒープを確保し続け  
アプリの確保メモリが非常に大きくなるため、スタックに移行できるものが  
あればスタックに移行したいと思い、このような質問をしました。

### 環境

  * Unity 5.0.1f1
  * .NET 2.0
  * C# 4.0


CC BY-SA 3.0
2015-05-25T02:33:32.850
10568
2015-08-27T06:12:09.747
2015-08-27T06:12:09.747
10455
5261
question
c# unity3d .net メモリ管理
C#でList<構造体>とした時、ヒープメモリなのかスタックメモリなのか？


`List`は、`class`とあるので、`new List<StructType>()`で生成されたオブジェクトはヒープに置かれるのでは？

<https://msdn.microsoft.com/ja-jp/library/6sh2ey19%28v=vs.110%29.aspx>


CC BY-SA 3.0
2015-05-25T02:46:17.430
10569
2015-05-25T02:46:17.430
845
10568
answer


> 構造体はスタック領域を使う

は正確ではありません。

構造体は置かれた場所をそのまま使うと言えばいいでしょうか。ローカル変数として構造体を宣言した場合、ローカル変数はスタックを使うため構造体はスタックを使うと言えます。しかし、クラスメンバーとした場合、そのクラス内に存在するだけで、クラスがどこに配置されたかに依存します。（そしてクラスはヒープを使うため構造体もヒープ上に存在することになります。）


CC BY-SA 3.0
2015-05-25T02:49:46.153
10570
2015-05-25T02:49:46.153
4236
10568
answer


`List<T>`を含めて多くのコレクション型はデータの格納に配列を利用していますが、C#の配列は[特に明示](https://msdn.microsoft.com/ja-
jp/library/cx9s2sy4.aspx)しない限りローカル変数であってもヒープに配置されます。


CC BY-SA 3.0
2015-05-25T10:54:54.353
10595
2015-05-25T10:54:54.353
5750
10568
answer


> UnityのC#ではヒープ領域がガベージコレクションで解放されないため、  
>  １度ヒープ領域が更新されるとアプリを落とすまでヒープを確保し続け  
>  アプリの確保メモリが非常に大きくなるため、スタックに移行できるものが  
>  あればスタックに移行したいと思い、このような質問をしました。

とのことですが、これは正しくないと思います。  
構造体(より正確には値型）のListを生成した場合、他の方が回答なさっているように、  
ヒープ領域（マネージヒープ）にその実体は存在することになります｡  
ただ、このマネージヒープ領域はガーベージコレクタの管理対象であり､参照が完全に無くなったListはどこかのタイミングで、ガーベジコレクトされます。

ただし、値型の内部にネイティブリソースへの参照などを保持している場合は､  
参照先のネイティブリソースは、その実体がアンマネージヒープに存在するので､  
当然ガーベジコレクタの管理対象には成りませんので､適宜管理が必要になると思います。

また、アンマネージリソースの管理手法としてありがちな、ファイナライザでのリソースの開放は値型の場合､ファイナライザを含むことができないので、参照型の作成を考慮すべきかも知れません。


CC BY-SA 3.0
2015-05-26T06:49:44.403
10635
2015-05-26T08:16:29.307
2015-05-26T08:16:29.307
7287
7287
10568
answer