1

I have a C# application which controls and monitors a PMAC controller. This application should be able to run for a few days at least, but I see that its memory usage would increase all the time. At first the memory usage is about 230M, and it will increase with 25M each hour.

I have found that memory does not increase unless I call the ReadDataFromDPRam() method.

I call this method 10msec intervals.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PmacServoRead
{
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)MotorNo.All)]
   public float[] CurPosition; // M4000, 
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)MotorNo.All)]
   public float[] CurVelocity;
   public int AmpEnable;
   public int PosLimit;
   public int NegLimit;
   public int HomeComp;
   public int DesiredVelocityZero;
   ...
}

[DllImport("Pcomm32.dll")]
public static extern IntPtr PmacDPRGetMem(UInt32 dwDevice, UInt32 offset, UInt32 count, IntPtr val);

public IntPtr GetDpramMemory(UInt32 devNo, UInt32 offset, UInt32 count, IntPtr val)
{
   return PmacDPRGetMem(devNo, offset, count, val);
}

private PmacServoRead m_PmacServoRead = new PmacServoRead();
private PmacInput m_PmacInput = new PmacInput();
int m_ReadSize = Marshal.SizeOf(typeof(PmacServoRead));
int m_ReadSizeDi = Marshal.SizeOf(typeof(PmacInput));

private int ReadDataFromDPRam()
{
   if (IsOpen == true)
   {
      IntPtr ptr1 = Marshal.AllocHGlobal(m_ReadSize);
      GetDpramMemory(DeviceNo, CcpPmacComm.DpramReadOffset, (uint)m_ReadSize, ptr1);
      m_PmacServoRead =(PmacServoRead)Marshal.PtrToStructure(ptr1, typeof(PmacServoRead));
      Marshal.DestroyStructure(ptr1, typeof(PmacServoRead));
      Marshal.FreeHGlobal(ptr1);

      ptr1 = Marshal.AllocHGlobal(m_ReadSizeDi);
      GetDpramMemory(DeviceNo, CcpPmacComm.DpramInputReadOffset, (uint)m_ReadSizeDi, ptr1);
      m_PmacInput = (PmacInput)Marshal.PtrToStructure(ptr1, typeof(PmacInput));
      Marshal.DestroyStructure(ptr1, typeof(PmacInput));
      Marshal.FreeHGlobal(ptr1);
   }
   return -1;
}

Please help me.

zx485
  • 28,498
  • 28
  • 50
  • 59
eun
  • 11
  • 1
  • Maybe it's about the GC: http://stackoverflow.com/questions/4257372/how-to-force-garbage-collector-to-run – Essigwurst Dec 09 '16 at 06:17
  • are you swallowing exceptions by any chance when calling `ReadDataFromDPRam`? in case `GetDpramMemory` is throwing exceptions, wrap `Marshal.FreeHGlobal` in a `finally` block to always free the pointer. – Ilian Dec 09 '16 at 06:29
  • 1
    You should switch from using `IntPtr` to `SafeHandle` it will let you make sure your unmanaged resources are deallocated in the event something goes wrong. [Here is a sample class](https://msdn.microsoft.com/en-us/library/microsoft.win32.safehandles.safehandlezeroorminusoneisinvalid(v=vs.80).aspx#Anchor_2) that will allocate and deallocate using `AllocHGlobal` – Scott Chamberlain Dec 09 '16 at 06:30

0 Answers0