一、内存占用大量资源的解决办法
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
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/aiops/289214.html