How can I make my C# program use less memory

This is sloppy I know and I'll modify this programming in the near future but can anyone have a look at this and tell me why it ends up eating up hundreds of megs of ram after a few days of running?  it's basically a syslog server program but i can't have it eating up hundreds of megs of ram.  Was hoping someone could take a look and tell me what to change or why it ends up eating up so much memory!!

thank you!
linuxroxAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

linuxroxAuthor Commented:
0
Jacques Bourgeois (James Burger)PresidentCommented:
I did not check everything, you might look further, but you seem to forget to Close some of your objects before losing them, so they probably hang in memory.

When a class has a Close and/or a Dispose method, you should usually call either of these before losing the variable. This specially true for classes that use unmanaged resources in the background, which is usually the case when you deal with network features. These can hang in memory even after the application is closed.

For instance, in backgroundWorker1_DoWork, you instantiate a local UdpClient object, but do not call Close or Dispose before exiting the method.

The same thing might happens with other variables in your code, but I do not have the time to check them all.
0
Daniel Van Der WerkenIndependent ConsultantCommented:
Try this. Let me know if it works.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Net.NetworkInformation;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public static string mypath = string.Empty;

        public Form1()
        {
            InitializeComponent();
        }

        public string TextValue
        {
            get
            {
                return textBox1.Text;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox2.Text = "514";
            foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                {
                    Console.WriteLine(ni.Name);
                    foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            comboBox1.Items.Add(ip.Address.ToString());
                        }
                    }
                }
            }
            comboBox1.SelectedItem = comboBox1.Items[0];
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox2.ReadOnly = true;
            textBox2.Enabled = false;
            backgroundWorker1.RunWorkerAsync(comboBox1.Text);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            string ip = (string)e.Argument;
            IPAddress ipAddr = IPAddress.Parse(ip);
            IPEndPoint anyIP = new IPEndPoint(ipAddr, 0);
            int port = Convert.ToInt32(textBox2.Text);

            using (UdpClient udpListener = new UdpClient(port))
            {
                byte[] bReceive; string sReceive; string sourceIP;

                while (true)
                {
                    try
                    {

                        if (!backgroundWorker1.CancellationPending)
                        {
                            bReceive = udpListener.Receive(ref anyIP);

                            sReceive = Encoding.UTF8.GetString(bReceive);

                            sourceIP = anyIP.Address.ToString();
                            backgroundWorker1.ReportProgress(0, sourceIP + "*" + sReceive);
                        }
                        else
                        {
                            e.Cancel = true;
                            backgroundWorker1.Dispose();
                        }
                    }
                    catch (Exception ex) { Console.WriteLine(ex.ToString()); }
                }
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            string[] args = ((string)e.UserState).Split('*');

            listBox1.Items.Insert(0, args[0] + "     " + args[1]);
            if (listBox1.Items.Count > 100)
            {
                listBox1.Items.RemoveAt(99);
            }

            label1.Text = Convert.ToString(listBox1.Items.Count);


            new Thread(new logHandler(args[0], args[1]).handleLog).Start();
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] args1 = ((string)e.Argument).Split('*');
            backgroundWorker2.ReportProgress(0, args1[0] + "*" + args1[1]);
        }

        private bool Is_Form_Loaded_Already(string FormName)
        {
            foreach (Form form_loaded in Application.OpenForms)
            {
                if (form_loaded.Text.IndexOf(FormName) >= 0)
                {
                    return true;
                }
            }
            return false;
        }

        class logHandler : Form
        {
            private string[] emailTriggers = new string[] { "link loss", "help please" };
            string outputPath = "";

            private string source; private string log;

            public logHandler(string sourceIP, string logData) /* Initialize object and clean up the raw data */
            {
                outputPath = mypath;
                source = sourceIP.Trim(); /* Client IP */
                log = logData.Replace(Environment.NewLine, "").Trim(); /* Syslog data */
            }

            public void handleLog()  /* Store the syslog and determine whether to trigger an email notification */
            {
                new Thread(new outputCsvRow(outputPath, new string[] { source, log }).addRow).Start();
                return;
            }

        }
        class outputCsvRow : Form
        {
            private string formattedRow = null;
            private string outputPath = null;

            public outputCsvRow(string filePath, string[] columns) /* Initialize object */
            {
                //frm1.listBox1.Items.Add("testttt");
                //MessageBox.Show(filePath);
                outputPath = filePath;
                formattedRow = (char)34 + DateTime.Now.ToString() + (char)34; /* Construct csv row starting with the timestamp */
                for (int i = 0; i < columns.Count(); i++) { formattedRow += "," + (char)34 + columns[i] + (char)34; }
            }

            public void addRow()
            {
                int attempts = 0;
                bool canAccess = false;

                if (!File.Exists(outputPath)) /* If the file doesn't exist, give it some column headers */
                {
                    using (StreamWriter logWriter = new StreamWriter(outputPath, true))
                    {
                        logWriter.WriteLine((char)34 + "Event_Time" + (char)34 + "," +
                          (char)34 + "Device_IP" + (char)34 + "," + (char)34 + "SysLog" + (char)34);

                        /* Thread safety first! This is a poor man's SpinLock */
                        while (true)
                        {
                            try
                            {
                                canAccess = true; /* Success! */
                                break;
                            }
                            catch (IOException ex)
                            {
                                if (attempts < 15) { attempts++; Thread.Sleep(50); }
                                else { Console.WriteLine(ex.ToString()); break; } /* Give up after 15 attempts */
                            }
                        }
                        if (canAccess) /* Write the line if the file is accessible */
                        {
                            logWriter.WriteLine(formattedRow);
                        }
                    }
                }
                return;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // Displays a SaveFileDialog so the user can save the Image
            // assigned to Button2.
            using (SaveFileDialog saveFileDialog1 = new SaveFileDialog())
            {
                saveFileDialog1.Filter = "CSV File|*.csv";
                saveFileDialog1.Title = "Save CSV File";
                saveFileDialog1.ShowDialog();

                // If the file name is not an empty string open it for saving.
                if (saveFileDialog1.FileName != "")
                {
                    // Saves the Image via a FileStream created by the OpenFile method.
                    using (FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile())
                    {
                        textBox1.Text = fs.Name;
                        mypath = fs.Name;
                    }
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

linuxroxAuthor Commented:
Ok Dan7el.  I'm running it right now and we log a LOT of things to this application.  logging all kinds of data from several hundred wireless access points and about 6 network switches.  lemme fire up Kiwi SyslogGen and flood it with logs and see what it does...hang on.
0
linuxroxAuthor Commented:
ok so right now i'm hitting it heavy and it's using 28 percent cpu and between 32 and 40 megs of memory.  I just stopped the flood and now it's staying solid at 35 megs of memory being used.  hmm, now it spiked up to 44 and isn't going back down.  i would have expected when the flood went away and since now it's not logging as much that it would use less memory.  hmm.
0
linuxroxAuthor Commented:
if you want, feel free to load it up in c# and do with it what you want.  u will see what i mean if you download kiwi syslog generator (free) and just point it to the ip address of the machine you run it on.  if you want i can zip up and send you the entire project.  there's really not much to it.
0
linuxroxAuthor Commented:
hold on here.  looks like there are some build errors so i guess i'm still running the old executable...lemme see what's up
0
linuxroxAuthor Commented:
here are the errors i get:

Error      1      'WindowsFormsApplication1.Form1' does not contain a definition for 'backgroundWorker1_RunWorkerCompleted' and no extension method 'backgroundWorker1_RunWorkerCompleted' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)      C:\syslogGUI\syslogGUI\syslogGUI\Form1.Designer.cs      66      120      syslogGUI
Error      2      'WindowsFormsApplication1.Form1' does not contain a definition for 'backgroundWorker2_ProgressChanged' and no extension method 'backgroundWorker2_ProgressChanged' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)      C:\syslogGUI\syslogGUI\syslogGUI\Form1.Designer.cs      72      114      syslogGUI
Error      3      'WindowsFormsApplication1.Form1' does not contain a definition for 'backgroundWorker2_RunWorkerCompleted' and no extension method 'backgroundWorker2_RunWorkerCompleted' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)      C:\syslogGUI\syslogGUI\syslogGUI\Form1.Designer.cs      73      120      syslogGUI
Error      4      'WindowsFormsApplication1.Form1' does not contain a definition for 'comboBox1_SelectedIndexChanged' and no extension method 'comboBox1_SelectedIndexChanged' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)      C:\syslogGUI\syslogGUI\syslogGUI\Form1.Designer.cs      91      81      syslogGUI
Error      5      'WindowsFormsApplication1.Form1' does not contain a definition for 'saveFileDialog1_FileOk' and no extension method 'saveFileDialog1_FileOk' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)      C:\syslogGUI\syslogGUI\syslogGUI\Form1.Designer.cs      114      94      syslogGUI
0
AndyAinscowFreelance programmer / ConsultantCommented:
As an aside make sure you understand how .net handles memory, specifically release of memory no longer used by the app.
Crudely said:  it doesn't release it when the object no longer 'exists', it releases it when the memory is actually required or when the app is closed or when it feels like it.  


ps.  There are even certain circumstances where the memory is never released until the system/app crashes due to out of memory error, apparently this behavior is by design on performance grounds of the garbage collection mechanism !
0
linuxroxAuthor Commented:
ok, how can i fix those errors I have there?  right now it's eating 370 megs of memory!!!  arghh!!  i'm trying to make this sufficient because I'd like to release it to some fellow network admins that need to gather logging information from their servers and/or switches.
0
linuxroxAuthor Commented:
i fixed those errors.  should i choose another programming language for something like this?  i mean, should I even be using .NET to create a multi-threaded server app like this?
0
Daniel Van Der WerkenIndependent ConsultantCommented:
Yeah. Sorry. I got rid of any methods that were not being used. So, for you the best way to fix them would be to go to the line in code where the error is and delete the addition. Or, conversely, re-add the event. I guess you fixed them. I assumed this would not be a big deal to solve.

The using statements I provided should fix your memory leak. Can you give it a whirl?

.NET is fine for this kind of app, you just need to close your IDisposables correctly. Wrapping them in the using statement does all that automagically.
0
linuxroxAuthor Commented:
hey Dan7el, yea it's running your code right now and eating up 145.1 megs which to me is still just too much for something like this.  i mean all it's doing is listening on udp port 514 and writing each line to a txt csv file.  gotta be a way for this to use far less memory i just don't know what to do on it!
0
Daniel Van Der WerkenIndependent ConsultantCommented:
Off hand, let's see what happens over time but we might need to consider opening and closing the documents for each write. That way we're not keeping the monster text in-memory. I'll look at it in a few.
0
linuxroxAuthor Commented:
For some reason it's not writing to the csv file.
0
linuxroxAuthor Commented:
ahh i see why it wasn't writing the file.  you modified it where it only would write the file if it didn't exist. think i corrected that now.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.