c#内存泄漏系统 [英] c# Memory leak system.timers

查看:206
本文介绍了c#内存泄漏系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个与I / O设备进行交互的程序,并且需要一种每隔x秒的时间轮询设备的方法,以便检查输入/输出连接。为了做到这一点,我使用了一个按钮来创建线程来进行轮询,使用定时器和定时器事件句柄。但是,我注意到,在任务管理器中,随着时间的流逝,慢慢地消耗更多的内存。以下是我认为与我的问题相关的一些代码片段。

I'm currently writing a program which interacts with I/O devices and needed a method of polling the device every x amount of seconds in order to check the in/out connections. To do this i've used a button which creates a thread to do the polling, using a timer and timer event handles. However, i notice that in the task manager, it is slowly eating up more memory as time goes by. Below is some snippets of code that are (i think) relevant to my problem.

创建线程的按钮:

private void btnConnect_Click(object sender, EventArgs e)
    {
        new Thread(start).Start();
    }

包含计时器的线程:

        public void start()
    {
        timer = new System.Timers.Timer(1000);
        timer.Elapsed += new ElapsedEventHandler(timerElapsed);
        timer.Enabled = true;
    }

ElapsedEventHandler:

The ElapsedEventHandler:

public void timerElapsed(object sender, ElapsedEventArgs e)
    {
        connect();
    }

最后的方法connect();:

And finally the method connect();:

public void connect()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text);
        int Port = int.Parse(txtPort.Text);
        string address = sb.ToString();

        //send data
        byte[] bData = new byte[71];
        bData[0] = 240;
        bData[1] = 240;
        bData[2] = 0;
        bData[3] = 1;
        bData[68] = 240;
        bData[69] = 240;
        bData[70] = this.CalculateCheckSum(bData);

        try
        {
            byte[] result = this.SendCommandResult(address, Port, bData, 72);
            if (result != null)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    txtOutput1.Text = (result[4] == 0x00 ? "HIGH" : "LOW"); // runs on UI thread
                });
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

    }

我很确定泄漏或者来自定时器,或者在方法connect()中使用的anon代表;任何人都有任何想法?

I'm pretty sure the leak is either coming from the timer, or the anon delegate used in the method connect();, anyone have any ideas?

推荐答案

每次点击按钮时都会创建一个新的计时器。另外,你没有参考它,所以它将被垃圾回收器销毁。没有必要在新线程上启动计时器,因为计时器会在新线程上引发Elapsed事件。

You are creating a new timer each time the button is clicked. Also, you are not keeping a reference to it, so it will be destroyed by the garbage collector. There is no need to start the timer on a new thread because the timer will raise the Elapsed event on a new thread.

class Form1 ...
{
    private System.Timers.Timer timer = null;

    public void start()
    {
    if (timer == null)
        {
        timer = new System.Timers.Timer(1000);
        timer.Elapsed += new ElapsedEventHandler(timerElapsed);
        }
    timer.Enabled = true;
    }

    ...
}

就内存泄漏而言,我不会假设内存泄漏只是因为在应用程序运行时看到内存使用情况看起来是随机的。当您正在.NET等复杂框架中运行时,这是正常的行为。每次定时器触发时,它都会调用您的connect方法来创建新对象。那些物体将留在记忆中,直到垃圾收集器绕过来清理它们。因此,看到内存迅速上升,然后几分钟后突然间再次下降,这并不奇怪。我不会怀疑一个问题,除非它在一段更长的时间内长期失控。

As far as a memory leak goes, I wouldn't assume there is a memory leak just because you see the memory usage fluctuating seemingly randomly while your application is running. That is normal behavior when you are running inside of a complex framework like .NET. Each time the timer fires, it's calling your connect method which creates new objects. Those objects will stay in memory until the garbage collector gets around to cleaning them up. As such, it's not at all surprising to see the memory creep up and then all of a sudden after a few minutes, drop back down again. I wouldn't suspect a problem unless it keeps growing out of control over a much longer period of time.

同样使用StringBuilder类的方法也很奇怪。你在做什么:

It's also strange the way you are using the StringBuilder class. What you are doing:

StringBuilder sb = new StringBuilder();
sb.Append(txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text);
string address = sb.ToString();

没有更好的效果(实际上有点差),而不仅仅是这样做:

is no better (in fact it's a bit worse), than just doing this:

string address = txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text;

如果您正在寻找一种更高效,更容易阅读的方式来尝试这样的事情

If you're looking for a more efficient, and possibly easier to read way to do it, try something like this

string address = string.Format("{0}.{1}.{2}.{3}", txtIPseg1.Text, txtIPseg2.Text, txtIPseg3.Text, txtIPseg4.Text);

然而,没有什么是跳出来,因为任何会导致内存泄漏的东西,所以除非你有很好的理由认为,我不用担心。

Nothing, however, is jumping out at me as being anything that would cause a memory leak, so unless you have good reason to think so, I wouldn't worry about it.

这篇关于c#内存泄漏系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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