非托管代码调用会导致严重的内存泄漏!

发布于 2024-09-03 20:13:59 字数 2116 浏览 7 评论 0原文

也许我需要更改标题,因为“非托管代码调用导致严重内存泄漏!”

泄漏约为 30M/小时,

我想也许我需要在这里完成我的代码,因为内存泄漏可能不是来自静态字符串,而我的真实代码从外部设备派生此字符串(请参阅附加的新代码)。所以我也处理非托管代码。泄漏有可能来自非托管代码吗?但我通过 Marshal.FreeCoTaskMem(pos); 释放了资源

   oThread2 = new Thread(new ThreadStart(Cyclic_Call));
   oThread2.Start();

  delegate void SetText_lab_Statubar(string text);
  private void m_SetText_lab_Statubar(string text)
  {
   if (this.lab_Statubar.InvokeRequired)
   {
    SetText_lab_Statubar d = new SetText_lab_Statubar(m_SetText_lab_Statubar);
    this.Invoke(d, new object[] { text });
   }
   else
   {
    this.lab_Statubar.Text = text;
   }
  }

  private void Cyclic_Call()
  {
   do
   {  
     //... ...
     ReadMatrixCode(Station6, 0, str_Code);
     this.m_SetText_lab_Statubar(str_Code[4]); 
     Thread.Sleep(100);
   }
   while (!b_AbortThraed);
  }

  private void ReadMatrixCode(Station st, int ItemNr, string[] str_Code)
  {
   IntPtr pItemStates = IntPtr.Zero;
   IntPtr pErrors = IntPtr.Zero;
   int NumItems = itemServerHandles.Length;

   m_SyncIO.Read(DataSrc, NumItems, itemServerHandles,
     out pItemStates, out pErrors); 
// This calls external dll which has some of "out IntPtr" 

   errors = new int[NumItems];
   Marshal.Copy(pErrors, errors, 0, NumItems);
   IntPtr pos = pItemStates;
   // Now get the read values and check errors

   for (int dwCount = 0; dwCount < NumItems; dwCount++)
   {
    result[dwCount] = (ITEMSTATE)Marshal.PtrToStructure(pos, typeof(ITEMSTATE));
    pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(ITEMSTATE)));
   }

   // Free allocated COM-ressouces
   Marshal.FreeCoTaskMem(pItemStates);
   Marshal.FreeCoTaskMem(pErrors);
   pItemStates = IntPtr.Zero; pErrors = IntPtr.Zero;
  }

m_syncIO是一个类,最后它会调用下面定义的COM组件

[Guid("39C12B52-011E-11D0-9675-1020AFD8ADB3")]
[InterfaceType(1)]
[ComConversionLoss]
public interface ISyncIO
{
    void Read(DATASOURCE dwSource, int dwCount, int[] phServer, out IntPtr ppItemValues, out IntPtr ppErrors);
    void Write(int dwCount, int[] phServer, object[] pItemValues, out IntPtr ppErrors);
}

Maybe I need change the title as "Unmanaged Code calling leads to heavy memory leak!"

The leak is around 30M/hour

I think maybe I need complete my code here because the memory leak maybe not from a static string whereas my real code derive this string from external device (see new code attached). so I handle also unmanaged code. Could it be possible the leak comes from unmanaged code? But I freed the resouce by Marshal.FreeCoTaskMem(pos);

   oThread2 = new Thread(new ThreadStart(Cyclic_Call));
   oThread2.Start();

  delegate void SetText_lab_Statubar(string text);
  private void m_SetText_lab_Statubar(string text)
  {
   if (this.lab_Statubar.InvokeRequired)
   {
    SetText_lab_Statubar d = new SetText_lab_Statubar(m_SetText_lab_Statubar);
    this.Invoke(d, new object[] { text });
   }
   else
   {
    this.lab_Statubar.Text = text;
   }
  }

  private void Cyclic_Call()
  {
   do
   {  
     //... ...
     ReadMatrixCode(Station6, 0, str_Code);
     this.m_SetText_lab_Statubar(str_Code[4]); 
     Thread.Sleep(100);
   }
   while (!b_AbortThraed);
  }

  private void ReadMatrixCode(Station st, int ItemNr, string[] str_Code)
  {
   IntPtr pItemStates = IntPtr.Zero;
   IntPtr pErrors = IntPtr.Zero;
   int NumItems = itemServerHandles.Length;

   m_SyncIO.Read(DataSrc, NumItems, itemServerHandles,
     out pItemStates, out pErrors); 
// This calls external dll which has some of "out IntPtr" 

   errors = new int[NumItems];
   Marshal.Copy(pErrors, errors, 0, NumItems);
   IntPtr pos = pItemStates;
   // Now get the read values and check errors

   for (int dwCount = 0; dwCount < NumItems; dwCount++)
   {
    result[dwCount] = (ITEMSTATE)Marshal.PtrToStructure(pos, typeof(ITEMSTATE));
    pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(ITEMSTATE)));
   }

   // Free allocated COM-ressouces
   Marshal.FreeCoTaskMem(pItemStates);
   Marshal.FreeCoTaskMem(pErrors);
   pItemStates = IntPtr.Zero; pErrors = IntPtr.Zero;
  }

m_syncIO is a class and finally it will call COM component which is defined below

[Guid("39C12B52-011E-11D0-9675-1020AFD8ADB3")]
[InterfaceType(1)]
[ComConversionLoss]
public interface ISyncIO
{
    void Read(DATASOURCE dwSource, int dwCount, int[] phServer, out IntPtr ppItemValues, out IntPtr ppErrors);
    void Write(int dwCount, int[] phServer, object[] pItemValues, out IntPtr ppErrors);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文