High memory usage of a windows forms method

2019-08-17 19:26发布

I have a c# windows forms application which uses too much memory. The peace of code, that is the problem is this

private void mainTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday)
                {
                    if (File.Exists(Globals.pathNotifFile + "1"))
                    {
                        File.Delete(Globals.pathNotifFile + "1");
                        File.Move(Globals.pathNotifFile, Globals.pathNotifFile + "1");
                    }
                    File.Move(Globals.pathNotifFile, Globals.pathNotifFile + "1");
                }

                if (DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
                {
                    return;
                }

                if (Globals.shotsFired != true)
                {
                    CreateDLclient();
                    Globals.shotsFired = true;
                }

                if (Globals.pathNotifFile == null)
                {
                    return;
                }

                var data = Deserialize();

                foreach (var notifyData in data.@new)
                {
                    if (notifyData.Status == "1" || notifyData.Status == string.Empty)
                    {
                        if (DateTime.Now >= Convert.ToDateTime(notifyData.DateTime))
                        {
                            if (notifyData.Message != string.Empty)
                            {
                                notifyData.Status = SendMessageToUser(notifyData.Message, notifyData.Company, notifyData.EmojiCode);
                                Serialize(data);
                            }
                            else
                            {
                                notifyData.Status = "3";
                                Serialize(data);
                            }
                        }
                        else if (DateTime.Now >= Convert.ToDateTime(notifyData.DateTime).AddMinutes(5))
                        {
                            if (notifyData.Message != string.Empty)
                            {
                                notifyData.Status = SendMessageToUser(notifyData.Message, notifyData.Company, notifyData.EmojiCode);
                                Serialize(data);

                            }
                            else
                            {
                                notifyData.Status = "3";
                                Serialize(data);
                            }
                        }
                    }
                }
            }

It causes a huge problem and the application crashes with 'out of memory' Can somebody give me an advice how can I reduce the memory usage of that. I've tried to invoke the GC /I know it is not a good idea/, but it didn't help.

Thank you in advance

1条回答
贼婆χ
2楼-- · 2019-08-17 19:48

You have not provided any info on which serializer you used in your program but I am quite inclined to think it is XMLSerializer because it is prone to memory leak and you said in your comment that the program is crashing after working more then 10-12 hours.

XmlSerializer uses assembly generation, and assemblies cannot be collected. As far as I know It does some caching for re-use but only for simple cases.

So if you have code like the following,which is called pretty often→

XmlSerializer xml = new XmlSerializer(typeof(MyObject), ....

Then you will get out of memory exception sooner or later.

Edit: How to avoid Memory Leak from XMLSerializer: Please have a look at the Topic Dynamically Generated Assemblies in the following link→MSDN Link If I just summarize what is written in there is that, you have a couple of ways.

1) You can use the following constructors to avoid dynamic assembly

XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)

2) Using a dictionary or hashtable, create your own caching

private Dictionary<Tuple<Type, XmlRootAttribute>, XmlSerializer> cacheSerializer = new Dictionary<Tuple<Type, XmlRootAttribute>, XmlSerializer>();
public XmlSerializer GetXmlSerializer(Type type, XmlRootAttribute root) {
    var key = Tuple.Create(type, root);
    XmlSerializer xmlSerializer;
    if (cacheSerializer.TryGetValue(key, out xmlSerializer)) {
        return xmlSerializer;
    }
    xmlSerializer = new XmlSerializer(type, root);
    cacheSerializer.Add(key,xmlSerializer);
    return xmlSerializer;
}
查看更多
登录 后发表回答