【C#】内存优化
一、内存占用大量资源的解决办法
1、定时清理
exe运行后占用内存一直增加导致软件越来越卡,调试发现是没调用一次某DLL函数就会增加一次,应该是内存泄露了,但就是没找到原因。
在主程序里加这段代码,定时清理内存,可暂时规避这一问题。
#region 内存回收 [DllImport("kernel32.dll")] private static extern bool SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize); private static void FlushMemory() { GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); } #endregion // 定时销毁不用的内存 private void timer1_Tick(object sender, EventArgs e) { FlushMemory(); }
出处: http://t.zoukankan.com/orange1438-p-4544951.html
2、通过检查工具定位
https://blog.csdn.net/jianingshow/article/details/79096637
CLR Profiler工具使用:链接
二、调用C++的DLL 后释放内存
如果是stdcall调用,就是由dll释放
如果是cdecl调用,就是谁调用谁释放
要想成功释放非托管代码分配的内存,必须先确定非托管代码的内存分配方式,才能在互操作是选择正确的方法释放非托管内存,在非托管代码中,有3种分配方式:
1、C语言:malloc 、free
2、C++:new、delete
3、COM:CoTaskMenAlloc、CoTaskMenFree
第三种方式是互操作默认的释放非托管内存的方法!也就是说,采用前两种方式分配的非托管内存,托管代码不能正确释放,必须由非托管方自己明确释放:
C++:
wchar_t* GetStringNew() { int iBufferSize = 128; wchar_t* pBuffer = new wchar_t[iBufferSize ]; if(NULL != pBuffer) { wcscpy_s(pBuffer, iBufferSize/sizeof(wchar_t), L"String from New"); } return pBuffer; } void FreeNewMemory(void* pBuffer) { printf("\n%d", pBuffer); if (NULL != pBuffer) { delete pBuffer; pBuffer = NULL; } }
C#:
[DllImport("NativeLib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode )] static extern string GetStringNew(); [DllImport("NativeLib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode )] static extern void FreeNewMemory(IntPtr pbuffer); IntPtr strPtr=GetStringNew(); string str=Marshal.PtrToStringUni(strPtr); FreeNewMemory(strPtr); //显示调用非托管释放内存函数释放内存,否则内存会泄露
出处:http://www.aiyiweb.com/Csharp/25018
/*******相与枕藉乎舟中,不知东方之既白*******/