什么会导致内存泄漏(或不断增加)?共享内存DLL + c#app

时间:2012-05-15 08:05:47

标签: c# c++ c

我有简单的共享内存DLL,用于从非托管应用程序到托管应用程序的进程间数据交换。 我注意到我的托管应用内存正在稳步增长。 有人可以建议可能的原因,如何找到它以及如何解决它? 以下代码的相关部分。

cpp SharedMem.DLL:

#pragma data_seg( ".IPC" )
....
double darr[MAXITEMS] = { 0.0 } ; 
....
#pragma data_seg()
....
double __stdcall MGetDouble (int idx)
{
    if ( idx>= 0 && idx < MAXITEMS)
    {
        return darr[idx]; 
    }
    else
    {
        return -1.0 ; 
    }
}

int __stdcall MSetDouble (int idx, double dvalue)
{
    if ( idx>= 0 && idx< MAXITEMS)
    {
        darr[idx] = dvalue;
        return idx;
    }
    else
    {
        return -1;
    }
}

和c#app:

[DllImport("SharedMem.DLL", CallingConvention = CallingConvention.StdCall)]
public static extern double MGetDouble(int index);

....

private void timer1_Tick(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(dosmth);
}

public object lockobj = new object();

public void dosmth(object o)
{
    if (Monitor.TryEnter(lockobj, 50))
    {
        ....
        double[,] matrix = new double[size, TSIZE];
        ....
        double gvd;
        int k;
        for (int i = 0; i < lines; i++)
            for (j = 0; j < TSIZE; j++) 
            {
                k++; //k can be up to 2k-4k typically
                gvd = MGetDouble(k);
                matrix[i, j] = gvd;
            }
            //... do the stuff
         Monitor.Exit(lockobj);        
     }

}

2 个答案:

答案 0 :(得分:2)

QueueUserWorkItem将在线程池(TP)上运行您的方法 - 如果先前的请求尚未完成,则新请求将阻止TP线程。经过一段时间后如果TP在空闲线程上运行不足,它将开始创建更多线程,每个线程至少消耗1MB的堆栈。

如果它对您的应用程序有意义,您可能希望在前一个完成之后运行新请求(例如 - 运行计时器以便它执行一次并使用Timer.Change来安排完成时的下一个执行时间处理)。

您还可以将WinDbgSOS extension一起使用,并使用DumpHeap / HeapStat等命令检查您的根,以查看您的内存到底在哪里。

答案 1 :(得分:1)

尝试这种方法:

public class doSmthClass()
{
    public void doSmthfromClass(...
}

并改变你的“路由器”做smth:

public void dosmth(object o)
{
  :
  var myInstance = new doSmthClass();
  myInstance.doSmthFromClass();
  :
}