1

編集:私の質問はTL;DR症候群に苦しんでいるようです。したがって、質問を読む代わりに、私が見つけた問題を示すビデオを見ることができます:http ://www.youtube.com/watch?v=xD0mRWJazis 。ビデオには表示されていません。デバッガーが接続されている場合にのみ発生します。


WorkflowInvokerWindows WorkflowFoundation4.0のを使用するアプリケーションがあります。Visual Studio 2010デバッガーがプロセスに接続されている間、プロセスを呼び出すたびにWorkflowInvoker.Invoke(...)、プロセスが数ギガバイトに成長し、コンピューターのメモリが不足してアプリケーションがフリーズし、デバッガーがクラッシュします(私のアプリケーションはそこに到達するのに1分ほどかかります)。デバッガが接続されていない場合、メモリリークは発生しません。

VisualStudio2010のステータスバーが表示されます

上のスクリーンショットに示されているように、ワークフローが呼び出されるたびに、同じワークフローを実行している場合でも、 VisualStudioのステータスバーに[ワークフローのシンボルの読み込み中...]と表示されます。これはメモリリークと関係があると思います。[ツール] >[オプション] >[デバッグ] >[シンボル]に移動し、 [指定されたモジュールのみ]を選択し、モジュールが指定されていないことを確認して、 [シンボルの自動ロード]でシンボルの読み込みを無効にしてみました。これは役に立ちませんでした。プロセスサイズは着実に増加し、VisualStudioはワークフローシンボルをロードしました。

以下は、問題を再現するための最小限のコードです。デバッガーの有無にかかわらずタスクマネージャーを実行しているときにタスクマネージャーを確認します(注意してください。デバッグ時にメモリをすぐに消費します!):

var workflow = new WorkflowInvoker(new Sequence());

while (true)
    workflow.Invoke();   ////  Memory leak!  //// 

メモリ消費量を表示しながら問題を示す、より拡張されたコンソールプログラムを以下に示します。1秒あたり約100の空のワークフローでのみ実行されます。デバッグせずに実行してみて(Ctrl+ F5)、デバッグして実行するのと比較してください(F5)。違いがすぐにわかります。サンプルを実行したくない場合は、以下のスクリーンショットとして結果を含めました。

using System;
using System.Activities;
using System.Activities.Statements;
using System.Diagnostics;
using System.Threading;

class Program
{
    static Timer Timer = new Timer(PrintMemory, null, 1000, 1000);
    static double PreviousSize;

    static void Main(string[] args)
    {
        Console.WriteLine("Debugger {0} attached.",
            Debugger.IsAttached ? "IS" : "is NOT");

        var workflow = new WorkflowInvoker(new Sequence());

        while (true)
        {
            workflow.Invoke();   ////  Memory leak!  ////
            Thread.Sleep(10);
        }
    }

    static void PrintMemory(object o)
    {
        double newSize = Process.GetCurrentProcess().PrivateMemorySize64 / 1048576d;
        Console.WriteLine("Grew by {0,5:F2} MB (total {1,7:F2} MB)",
            newSize - PreviousSize, newSize);
        PreviousSize = newSize;
    }
}

デバッグなしとデバッグありのプログラムの30秒の実行は次のとおりです。

含まれているサンプルアプリケーションは、左側にデバッガーなしで30秒間実行され、33 M​​Bの安定したメモリフットプリントを示し、右側にあるデバッガーは、毎秒43 MBずつ増加し、わずか30秒後に1.6GBに達するメモリフットプリントを示しています。

ご覧のとおり、メモリは毎秒約43MBずつ増加します。アプリケーションをデバッガーで実行できる必要があります。助言がありますか?

編集:私はここでこの問題の接続バグを開きました。

編集:まあそれはバストでした。どうやらConnectは最新かつ最高のもののためだけのものです。VS2012は10分前にRTMを実行しましたが、connectはVS2010のフィードバックを受け付けていません。次の目的地は、WF4フォーラムへの投稿です。成功を祈っている。

4

3 に答える 3

2

私が投稿したMSDNフォーラムの質問でTimLovell-Smithが正しく指摘しているように、これは.NET4.5で修正された.NET4.0の既知のバグです。幸い、.NET 4.5をインストールするだけで、 VisualStudio2010の問題も修正されます。

于 2012-10-03T21:06:39.180 に答える
1

私にはHeisenbugのように聞こえますが、@ dbam987は、デバッグ時にガベージコレクターが通常のビルドとは異なる動作をすることをすでに指摘しているため、それほど驚くことではありません。

アプリのメモリ動作について知りたい場合は、テストする必要がある唯一の方法は、デバッガーが接続されていないリリースビルドを使用することです。さらに言えば、デバッグせずにVS2012から起動するのではなく、エクスプローラーから起動します。

デバッガがなければメモリリークは発生しないとの指摘がありましたが、心配する必要はありません。したがって、これは、1つを探し始めたときにのみHeisenbugに変わります。

于 2012-09-30T09:37:05.223 に答える
0

WorkflowInvokerではなくWorkflowApplicationコンポーネントを使用してワークフローを起動してみてください。その設定は、 WorkflowInvokerの使用と非常によく似ています。

using System;
using System.Activities.Statements;
using System.Threading;

public class Program
{
    public static void Main(string[] args)
    {
        // Setup the sample workflow.
        var workflow = new Sequence
            {
                Activities =
                    {
                        new WriteLine { Text = "Hello World!" },
                        new Delay { Duration = TimeSpan.FromSeconds(3) },
                        new WriteLine { Text = "Done!" }
                    }
            };

        // Setup the workflow host.
        var syncWorkflowEvent = new AutoResetEvent(false);
        var workflowApp = new WorkflowApplication(workflow);
        workflowApp.Completed = eventArgs => syncWorkflowEvent.Set();
        workflowApp.Run();
        syncWorkflowEvent.WaitOne();
    }
}
于 2012-10-03T17:22:36.793 に答える