0

C# ソケットとアンマネージ C++ DLL を集中的に使用するプログラムを作成しましたが、このような便利な機能はほとんどありません。

[DllImport(DLLName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    [return: MarshalAs(UnmanagedType.LPStr)]
    private static extern void calcData(float ask, float bid, float volume, float lastTrade, string symbolName, TQuoteType type, IntPtr str, out int size);

私は 8 ~ 10 のスレッドで C# マルチスレッドを使用しており、すべてのスレッドが 200 ミリ秒ごとにソケットでデータを送信しています。
プログラムは Windows 7 と Windows Server 2008 では正常に動作しますが、XP と Windows Server 2003 では2 日間の動作後にメモリ不足システム例外が発生します。RAM の最大使用量が 17 MB であるため、何が起こっているのかわかりません。誰でもこの問題を解決するのを手伝ってもらえますか?

4

3 に答える 3

0

ヒープの断片化が原因だと思います。

Windows XP および 2003 では、プログラムを数日間実行し、C++ コードで malloc/free または new/delete を使用してヒープからメモリを割り当て/解放すると、デフォルトでヒープの断片化の問題が発生します。ヒープの断片化とは、使用可能なメモリが連続していない小さなブロックに分割されている状態です。ヒープが断片化されている場合、ヒープ内の使用可能なメモリの合計が要求を満たすのに十分な場合でも、メモリの割り当てが失敗する可能性があります。これは、単一のメモリ ブロックでは十分な大きさがないためです。

Windows XP および 2003 の後、MS はLow-fragmentation Heapを有効にします。これにより、この問題が修正されます。アプリケーションは、ヒープに対して LFH を有効にする必要はありません。Windows XP および 2003 では、コードで有効にできます。このページでは例を示します。(別のヒープを作成する必要はありません。API GetProcessHeap を使用して既定のヒープを取得するだけで済みます。

于 2013-08-19T16:13:27.787 に答える
0

XP / 2003 マシン上の他のプロセスによる異常なメモリ消費を探してみましたか。

プログラムが他の環境で正常に動作することを考えると、問題を引き起こしているのはプログラムではなく、単なる症状である可能性があります。

別の方法として、プログラムが終了したときにダンプをキャプチャして、WinDb または Visual Studio でロードすることもできます。

http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx

ProcDump.exe -ma -t PROCESS.EXE
于 2013-08-19T07:18:38.097 に答える
0

最初に、メモリ リークがあるかどうかを判断します。これにはタスク マネージャーを使用せず、代わりに perfmon を使用してください。タスク マネージャーの [メモリ使用量] 列はワーキング セットにすぎず、これはアプリの全体像ではありません。したがって、perfmon を起動し、見やすいレポート モードに切り替えて、既存のカウンターを削除します。次に、プロセスに次のカウンターを追加します。

Process | Working Set
Process | Virtual Bytes
Process | Private Bytes
.NET CLR Memory | # Total reserved Bytes
.NET CLR Memory | # Total committed Bytes
.NET CLR Memory | Large Object Heap size

32 ビット アプリを使用していると思われるため、最大仮想アドレス空間は 2GB です。アプリを実行し、定期的にカウンターをチェックします。プロセスの場合 | Virtual Bytes が 1.9GB 近くになると、奇妙な方法で崩壊します。断片化も問題になる可能性がありますが、それはラージ オブジェクト ヒープ内のネイティブ メモリとマネージド オブジェクトにのみ影響します。LOH が高くなりすぎる場合は、LOH のフラグメンテーションを示している可能性があります。

メモリ リークが見られる場合は、リークがマネージ コードにあるのかネイティブ コードにあるのかを判断できます。.NET CLR メモリの場合のマネージ リーク | # 総予約バイト数がかなり高くなります。.NET CLR メモリの場合のネイティブ リーク | # 総予約バイト数は低いままで、.NET CLR メモリ | # 総予約バイト数が高くなります。マネージ メモリは、プロセスの仮想アドレス空間全体のサブセットであることに注意してください。

断片化やメモリ リークが発生していないと思われる場合は、.NET がメモリ不足の例外をスローしている可能性があります。これは珍しいことですが、それほど珍しいことではありませ。この時点で、デバッガが必要になります。

于 2013-08-19T17:04:30.850 に答える