3

In the project I made was a memory leak. I rewritten all the functions to fix some, but there was still one left:

The program has an object array of panels which grows everytime I put a new one in. When it reaches 400 panels, it deletes the oldest to free some memory.

What I don't understand is the following:

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

When I use the code above the memory usage still keeps increasing... Can someone please explain why I have to dispose the panel first before I set panels to null?

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels[0].Dispose();
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

Thanks in advance!

EDIT @ Steve B:
The program makes a new panel: panel currentPanel;
When there is a new panel I declare currentPanel: currentPanel = new Panel();
After that I call this function: setCurrentPanelConfiguration:

public void setCurrentPanel()
{
  currentPanel.Name = "panel" + panels.Length;
  currentPanel.Size = new System.Drawing.Size(485, 75);
  currentPanel.BackColor = Color.Transparent;
}

To fix a scroll bug I use a Panel HistoryPanel where I put the currentPanel:

HistoryPanel.Controls.Add(currentPanel);

Then I add all the controls: the username, current time and avatar.

To save the panel I add it to the array panels after I created a space as shown above:
panels[panels.Length-1] = currentPanel;

I use an array because the history shows the newest one on top. To do that every time I have to shift all panels 80px down.

8
  • 1
    You can use the garbage collector to free memory: GC.GetTotalMemory(true) Commented Jan 8, 2013 at 9:01
  • 1
    If I am not mistaken, you have to call dispose on the panels first. Otherwise, they will not bee freed. Commented Jan 8, 2013 at 9:01
  • If I use de garbage collector, where do I have to put it in the code and have I to create a destructor or something for the array? Commented Jan 8, 2013 at 9:03
  • Isn't manually calling the garbage collector a bad idea? Isn't the garbage collector supposed to detect free-able object itself and collect it when the program is idle? Commented Jan 8, 2013 at 9:05
  • 1
    AFAIK the garbage collector shouldn't ever be called expicitly unless you know it needs to be invoked (handling unmanaged resources?). FYI if you make panels a collection (i.e. List<>) it would fit nicely in your code: panels.RemoveAt(0); and you're done. Commented Jan 8, 2013 at 9:07

2 Answers 2

11

Because setting something to null does not dispose of it, it just dereferences it - the garbage collector isn't monitoring your assignments to check for your null references, it does it when it wants (all else being equal) or when explicitly told to do so.

In short, because null and memory management are different things.

Sign up to request clarification or add additional context in comments.

1 Comment

Just imagine you have a box and you just take out whats inside. The box is still there. Thats what you are doing. Delete the entire node.
3

In addition to what Grant Thomas said, why don't you use a List<Panel>, which is much easier to manage?

The code would read like this (assuming that panels was declared as List<Panel>):

Panel p = panels[0];
panels.RemoveAt(0);  // This removes the first element

p.Dispose(); // This disposes of the element

If you want to keep your code, it should read as follows:

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)

// Dispose of every element in the array
for (int i = 0; i < panels.Length; i++)
    panels[i].Dispose();

// The following line is unneccessary, as the variable is re-assigned anyway
// panels = null; //empty object array

panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

1 Comment

You are right! I was looking for a List because I was used to in Java, but it didn't want to work at all, so I made this solution and worked fine. The variable panels is declared like a normal array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.