我创建了大量使用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 is发送一次数据。
程序在Windows7和Windows 2008上运行良好,但在XP和Windows 2003上,在运行2天后出现内存系统异常。我不明白发生了什么,因为内存的最大使用量是17‘t。有人能帮我解决这个问题吗?
发布于 2013-08-19 07:18:38
您是否尝试过寻找XP / 2003机器上其他进程所消耗的任何异常内存。
考虑到该程序在其他环境下运行良好,甚至可能不是您的程序造成问题,而是一个症状。
作为另一种选择,您可以尝试在程序终止时捕获转储,并使用WinDb或Visual加载转储。
http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx
ProcDump.exe -ma -t PROCESS.EXE发布于 2013-08-19 16:13:27
我认为这是由堆碎片造成的。
如果程序运行数天,并且您的C++代码使用malloc/free或新/delete从堆中分配/释放内存,默认情况下,在Windows和2003上,您将遇到堆碎片问题。堆碎片是一种状态,在这种状态下,可用内存被分解为小的、不连续的块。当堆被碎片化时,即使堆中的可用内存总量足以满足请求,内存分配也可能失败,因为没有一个内存块足够大。
在Windows和2003之后,MS启用了低碎裂堆,它解决了这个问题,应用程序不需要为它们的堆启用LFH。在Windows和2003上,您可以通过代码启用它。这个页面给出了一个例子。(您不需要创建另一个堆,只需要使用API GetProcessHeap获得默认堆。
发布于 2013-08-19 17:04:30
首先确定是否有内存泄漏,不要为此使用任务管理器,而是使用perfmon。任务管理器中的Mem使用列只是工作集,这肯定不是应用程序的完整图片。因此,启动perfmon,切换到report模式,这更容易查看,并删除现有的计数器。然后为您的进程添加以下计数器:
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。运行您的应用程序,并定期检查计数器。如果Process \ Virtual接近1.9GB,那么事情就会以奇怪的方式分崩离析。碎片也可能是问题,但这只会影响大对象堆中的本机内存和托管对象。如果LOH过高,这可能意味着LOH的碎裂。
如果确实看到内存泄漏,则可以计算泄漏是在托管代码中还是在本机代码中。如果.NET CLR内存\\总保留字节变得相当高,则托管泄漏。本机泄漏,如果.NET CLR内存\总保留字节保持较低,而.NET CLR内存\总保留字节保持较高。请记住,托管内存是进程总虚拟地址空间的子集。
如果您认为您没有看到碎片或内存泄漏,那么有可能是.NET抛出内存之外的异常,这是一条红线鲱鱼,还有其他的问题。这是不寻常的,但也并非不寻常。此时,您需要一个调试器。
https://stackoverflow.com/questions/18307866
复制相似问题