0

私はvb.netで次のコードを持っています:

Public Async Function WriteData(buffer() As Byte, offset As Integer, count As Integer) As System.Threading.Tasks.Task
        Try
            Using data_writer = IO.WindowsRuntimeStreamExtensions.AsStreamForWrite(_outputStream)
                Await data_writer.WriteAsync(buffer, offset, count)
                Await data_writer.FlushAsync
            End Using
        Catch ex As Exception
             Logger.Write(ex)
        End Try
    End Function

関数 WriteDate を呼び出しすぎているのですが、関数を呼び出すたびにメモリが増加していることに気付きます。Using の使用により、datawriter ストリームと _outputStream が破棄されていることがわかります。

vs プロファイラーを実行すると、コード内の「バッファー」であるバイト配列によってメモリの 95% が過度に予約されていることがプロファイラーによって示されます。

1- 私のコードに問題はありますか? 2-バイト配列をクリアするにはどうすればよいですか?

-- その関数の Await data_writer.FlushAsync 行の後に次のコードを追加しました。

buffer = Nothing
GC.Collect()

そのため、メモリは以前のように増加しませんが、アプリで WriteData を呼び出しすぎて、GC.Collect を呼び出しすぎることは推奨されていないことを読みました。

GC.Collect を呼び出さないと、メモリは 300 MB にジャンプします。GC.Collect() を使用すると、メモリは 50 MB を超えません。

ご意見をお聞かせください。

ありがとう

4

3 に答える 3

3

GC を制御しようとする前に、GC の仕組みを理解する必要があります。ガベージ コレクションは、主に「メモリ プレッシャ」によって駆動されます。つまり、プログラムがすぐに使用できるメモリが不足している場合、一部を解放するためにコレクションが発生します。

呼び出しなしでメモリ使用量が 300MB にGC.Collectなるのは、コードの実行時に .NET に負荷がかからないためです。プレッシャーがかかっていないため、コレクションの実行に時間を無駄にすることはありません。割り当てられた 300MB のメモリは積極的に使用されていません。呼び出しているからといって、コードが魔法のように効率的になっているわけではありません。Collectしかし、その時点で .NET を整理する理由はありません。

私のアドバイスは次のとおりGC.Collectです。アプリケーションのメモリ使用量を減らす具体的かつ意味のある理由がない限り、 を呼び出さないでください。必要に応じて、ガベージ コレクターはそのメモリ自体を収集します (使用量が増加し、定期的に 50 MB まで低下する可能性があります)。

于 2013-04-08T10:44:37.123 に答える
2

これは一般的な GC の問題であり、Phone や Await に固有のものではありません。確かに問題の解決には役立ちませんが。問題は、バッファが大きすぎて 85KB を超えていることです。大きすぎて GC で簡単に圧縮できないため、Large Object Heap に割り当てられます。ジェネレーション 0 には、コレクションをトリガーするのに十分な小さなオブジェクトがなくなりました。LOH は gen#2 のコレクション中にのみクリーンアップされるため、GC.Collect() を呼び出すことは確かに回避策です。

Collect() を呼び出さなくても済むようにするための 2 つの基本的な戦略。最初に、gen#0 に割り当てられるのに十分小さい小さいバッファーを使用することを強く推奨します。少しの作業を行うことは常に良いことです。Await キーワードは、コードの些細な変更を行うのに本当に役立ちます。わかりにくい、発信者が見えない。

2 番目の戦略は、バッファーを再利用して、そのうちの 1 つだけが必要になるようにすることです。それがどれほど簡単かは、発信者がどのように見えるかに大きく依存します。

于 2013-04-08T11:27:11.647 に答える
0

他のシナリオでは、HTTP サーバーで同じ問題が発生しましたが、本当の解決策を見つけました。

AsStreamForWrite() を使用しないでください。WinPRT IOuputStream を直接使用してください (VB でも可能だと思います)。

于 2014-08-27T18:44:17.060 に答える