我的C#应用​​程序的内存使用量增加 [英] The memory usage of my c# application increase

查看:77
本文介绍了我的C#应用​​程序的内存使用量增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好

我有一个c#应用程序,用于控制和监视PMAC控制器.该应用程序至少应该能够运行几天,但是我发现它的内存使用量会一直增加.最初,内存使用量约为230M,并且会增加 每小时25M.

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. 

我发现除非调用ReadDataFromDPRam()方法,否则内存不会增加.

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

我称此方法为10毫秒间隔.

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;
}

请帮助我.

推荐答案


嗨恩,


Hi  euns,

>>我发现除非调用ReadDataFromDPRam()方法,否则内存不会增加

据我所知,在您的ReadDataFromDPRam()方法中,您使用AllocHGlobal分配了一些内存(当我们分配非托管"内存时,运行时垃圾收集器不会管理内存.您必须管理内存,这意味着什么时候 您不再使用它,则需要释放内存).

As far as I know, In your ReadDataFromDPRam() method, you allocate some memory with AllocHGlobal ( when we allocate "unmanaged" memory, the run-time garbage collector does not manage memory. You have to manage the memory, which means that when you no longer use it, you need to release the memory).

C#不会自动释放由Marshal.AllocHGlobal分配的内存.必须通过调用Marshal.FreeHGlobal释放该内存,否则它将被泄漏.

C# will not automatically free memory allocated by Marshal.AllocHGlobal. That memory must be freed with a call to Marshal.FreeHGlobal or else it will be leaked.

您还可以定义一个智能指针,以包装IntPtr并将对象包装在using语句中,或者通过允许在终结器运行时将其释放来实现.以下Struct包装器供您参考.

You can also define a smart pointer to wrap the IntPtr and wrapping the object in a using statement or by allowing it to be freed when the finalizer runs. The following Struct Wrapper for your reference.

    [StructLayout(LayoutKind.Sequential)]
    public class INNER
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        public string field1 = "Test";
    }


    class IntPtrStructWrapper : IDisposable
    {
        public IntPtr Ptr { get; private set; }

        public INNER inner { get; private set; }

        public IntPtrStructWrapper(object obj)
        {
            if (Ptr != null)
            {
                Ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
               // Marshal.StructureToPtr(obj, Ptr, false);
                inner = (INNER)Marshal.PtrToStructure(Ptr, typeof(INNER));

            }
            else {
                Ptr = IntPtr.Zero;
            }
        }

        ~IntPtrStructWrapper()
        {
            if (Ptr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(Ptr);
                Ptr = IntPtr.Zero;
            }
        }

        public void Dispose()
        {
            Marshal.FreeHGlobal(Ptr);
            Ptr = IntPtr.Zero;
            GC.SuppressFinalize(this);
        }

        public static implicit operator IntPtr(IntPtrStructWrapper w)
        {
            return w.Ptr;
        }
    }

Marshal.PtrToStructure方法(IntPtr,类型):
https://msdn.microsoft.com /en-us/library/4ca6d5z7%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Marshal.PtrToStructure Method (IntPtr, Type):
https://msdn.microsoft.com/en-us/library/4ca6d5z7%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396


最好的问候,


Best Regards,

吕汉楠


这篇关于我的C#应用​​程序的内存使用量增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆