トップ回答者
Bilittableデータのピン止めは不必要でしょうか?

質問
-
いつもお世話になっております.恒です.
環境:WindowsXPSP3
開発言語VS2010Express C#
.NetFramework4.0質問:
アンマネージなDLLを使用する時に,
Blittableなマネージデータを[In],[Out]属性で
やりとりする時は,ピン止めが不必要
という命題は正しいでしょうか?内容詳細:
IntelのMKLのライブラリのExampleのFFTのソース
を眺めていたのですが,
<http://software.intel.com/en-us/articles/using-intel-mkl-in-your-c-program/>
DLLに直接doubleのマネージの配列を渡しています.
<MarshalAs(UnmanagedType.LPArray)>とかもGCHandleとかのピン止めも行っていません.<http://msdn.microsoft.com/ja-jp/library/75dwhxf7.aspx>
を読んでみると,
○blittable型の一次元配列はBlittable。 (型の中に可変配列が含まれる場合は別)
○blittable 型の配列は、最適化のために、マーシャリング時にコピーされるのではなく固定されます
と書いてあります.という事はピン止めは必要ないのかなと思いました.やってみた事:ピン止め有りと無しで100000回演算させて,エラーが起きない事を確認しました.
以上
回答
-
-
非同期IOとかもそうですが、アンマネージメソッドを呼び出し、その中でスレッドその他で別の処理が動きだし、メソッド呼び出しそのものはreturnしてしまう場合です。
この場合、呼び出し側のマネージスレッドは次の処理に進むなどしてオブジェクトの生成・破棄が行われるとガベージコレクタが動き出す可能性があります。そうなるとアンマネージメソッドに渡したオブジェクトが移動されてしまう可能性が出てきます。…って話をすると、じゃあサーバーガベージコレクションや.NET 2.0 SP1(だっけ?)の同時実行ガベージコレクション、.NET 4のバックグラウンドガベージコレクションならアンマネージメソッドの実行中にもGCが動き出す可能性があって固定すべきじゃないかという話にもなりますが。同時実行は大丈夫かな…?
それとは別の話で、ガベージ コレクションの基礎には
大きなオブジェクト ヒープは圧縮されません。
大きなオブジェクト ヒープには、85,000 バイトを超えるオブジェクトが格納されます。 大きなオブジェクト ヒープの中で特に大きなオブジェクトは、通常は配列になります。
という記述もあり、この条件を満たす配列はそもそも固定不要です。
# この仕様が今後変わらないという保証はありませんが。- 回答としてマーク 恒岡 2012年2月9日 14:16
すべての返信
-
-
恒です.
お二方共お返事ありがとうございます.
○引数を配列にしたら,マーシャラが自動的にピン止めする
○Blittableとピン止めは関係ない
と了解いたしました.後で回答マークつけさせていただきます.2点ほど少し違うケースでの確認なのですが,
確認1.
アンマネージDLL側でメモリ確保,解放を行い,そのDLL内部の
配列データに対するメモリアドレスへのポインターIntPtrからマネージの配列データを受け取る時に,Marshal.Copyを
使用していれば,ピン止めは必要ない.
具体的なコード(すいません.C#のフォーラムなのにVBのコードで)
Dim ImageBuffer As IntPtr Dim ImageLength As Integer アンマネージDLLのメソッドでbyrefでImageBuffer取得 アンマネージDLLのメソッドでbyrefでImageLength取得 ~ Dim ExternalBuffer() As Byte ReDim ExternalBuffer(ImageLength - 1) Marshal.Copy(ImageBuffer, ExternalBuffer, 0, ImageLength) '<---ここピン止めいらない?
確認2:
Marshal.Copyを使用してバイト配列をIntPtrに与える場合,
ピン止めは必要ない.具体的なコード
バイト配列のデータから白黒ビットマップを作成する時のコードです.Using bmpLocalImage As Bitmap = New Bitmap(w, h, Imaging.PixelFormat.Format8bppIndexed) Dim bmpPalette As System.Drawing.Imaging.ColorPalette bmpPalette = bmpLocalImage.Palette For i = 0 To 255 bmpPalette.Entries(i) = Color.FromArgb(i, i, i) Next bmpLocalImage.Palette = bmpPalette Dim bmpData As System.Drawing.Imaging.BitmapData = Nothing try bmpData = bmpLocalImage.LockBits(New Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed) Dim ptrScan0 As IntPtr = bmpData.Scan0 Marshal.Copy(ExternalBuffer, 0, ptrScan0, w * h) '<---ここピン止めいらない? Finally If bmpData IsNot Nothing Then bmpLocalImage.UnlockBits(bmpData) End If End Try ~処理 bmpLocalImage.Dispose() End Using
一応,両方とも回数こなしてもエラーはおきないようです.ピン止めいらないのかと思います。 -
非同期IOとかもそうですが、アンマネージメソッドを呼び出し、その中でスレッドその他で別の処理が動きだし、メソッド呼び出しそのものはreturnしてしまう場合です。
この場合、呼び出し側のマネージスレッドは次の処理に進むなどしてオブジェクトの生成・破棄が行われるとガベージコレクタが動き出す可能性があります。そうなるとアンマネージメソッドに渡したオブジェクトが移動されてしまう可能性が出てきます。…って話をすると、じゃあサーバーガベージコレクションや.NET 2.0 SP1(だっけ?)の同時実行ガベージコレクション、.NET 4のバックグラウンドガベージコレクションならアンマネージメソッドの実行中にもGCが動き出す可能性があって固定すべきじゃないかという話にもなりますが。同時実行は大丈夫かな…?
それとは別の話で、ガベージ コレクションの基礎には
大きなオブジェクト ヒープは圧縮されません。
大きなオブジェクト ヒープには、85,000 バイトを超えるオブジェクトが格納されます。 大きなオブジェクト ヒープの中で特に大きなオブジェクトは、通常は配列になります。
という記述もあり、この条件を満たす配列はそもそも固定不要です。
# この仕様が今後変わらないという保証はありませんが。- 回答としてマーク 恒岡 2012年2月9日 14:16
-
>非同期IOとかもそうですが、アンマネージメソッドを呼び出し、その中でスレッドその他で別の処理が動きだし、メソッド呼び出しそのものはreturnしてしまう場合です。
>この場合、呼び出し側のマネージスレッドは次の処理に進むなどしてオブジェクトの生成・破棄が行われるとガベージコレクタが動き出す可能性があります。そうなるとアンマネージメソッドに渡したオブジェクトが移動されてしまう可能性が出てきます。お返事ありがとうございます。なるほどです。
>…って話をすると、じゃあサーバーガベージコレクションや.NET 2.0 SP1(だっけ?)の同時実行ガベージコレクション、.NET 4のバックグラウンドガベージコレクションならアンマネージメソッドの実行中にもGCが動き出す可能性があって固定すべきじゃないかという話にもなりますが。同時実行は大丈夫かな…?
サーバGCは使ってないと思いますが、そのほかは怖いです。けど私の能力では検証不能です。アンマネージメソッドに渡されたマネージオブジェクトのメモリアドレスをアンマネージメソッドの実行中か終わった直後に取得できればいいのかな?
>それとは別の話で、ガベージ コレクションの基礎には
大きなオブジェクト ヒープは圧縮されません。
大きなオブジェクト ヒープには、85,000 バイトを超えるオブジェクトが格納されます。 大きなオブジェクト ヒープの中で特に大きなオブジェクトは、通常は配列になります。
>という記述もあり、この条件を満たす配列はそもそも固定不要です。
># この仕様が今後変わらないという保証はありませんが勉強になります。メモリコンパクションの対象にならないということは、高速化とメモリ断片化の危険とのトレー
ドオフという事でしょうか。という事はもし85000バイト以上の配列データをある程度長く保持するなら、
GenericListとかに移し替えておいた方がいいのでしょうか?
-
ググると
<http://msdn.microsoft.com/ja-jp/magazine/cc534993.aspx>
を見つけました.
># この仕様が今後変わらないという保証はありませんが
という事ですね.
他の疑問は,大分元のスレからずれてきたので,再度勉強しなおして
出直してきます.皆様方ありがとうございました.