Removing memory leaks with memory profiling

Although, from one perspective, memory leaks are not possible with Java, failure to dereference objects will still, in the end, monopolize memory and potentially cause problems with your software. By using the diff functionality of the memory profiling feature, you will uncover poor object allocation/deallocation practice within the code.

To locate and detect memory problems:

  1. Select the Memory Profile tab.

  2. If you performed the Further Work section for memory profiling, skip this step; otherwise, select the menu item Memory Profile->Show/Hide Data->Diff with Previous Snapshot.

Two new columns have appeared - Referenced Objects Diff AUTO and Referenced Bytes Diff AUTO. These columns contain a diff between each snapshot and the previous snapshot for every listed method; the word "referenced" refers to those objects for which a reference exists following a snapshot. It is also possible for the user to diff any two selected snapshots; this custom diff would be labeled USER to differentiate it from the AUTO diff you will be studying. (Note that a blank cell in any diff column means the object did not exist in the previous snapshot.)

Recall that the snapshots for this Tutorial occurred immediately after each garbage collection. This means that any object references uncovered by a diff are suspicious; referenced objects can not be deallocated by the garbage collector.

  1. Sort by the column Referenced Objects Diff AUTO by clicking on the column header.

  2. Search the various snapshots for a method that recurrently is responsible for continuously referenced objects.

Have you noticed that the GetChannels() method reappears throughout? Perhaps you should look at the code to understand why this method is so often associated with continuously referenced objects.

  1. Left-click any reference to the GetChannels() method in the first column of the table.

  2. Scroll the Text Editor until you can view the GetChannels() method.

Inspection of the GetChannels() function reveals that it creates ten new channels each time it is called - which means ten channels should be removed (i.e. dereferenced) elsewhere in the code. This dereferencing is the responsibility of the ReleaseChannels() method, located right below the definition of GetChannels(), and the for statement of this method has been improperly written. Currently, the ReleaseChannels() method only dereferences nine objects. You need to fix the code.

  1. Modify the for statement of the ReleaseChannels() method as follows (you are adding an =):

Change the code from

for (i=0;i<10;i++)

to

for (i=0;i<=10;i++)

  1. Select the menu item File->Save.

  2. Right-click the tab for the source file you have just modified and select Close.

This should fix the problem. Before redoing you manual test to verify if the memory error was fixed, move on to the Performance Profile viewer and see if you can streamline the performance of the UMTS base station code.

As for the other methods that appear to continuously reference objects following garbage collection - are they also leaking? That's for you to figure out!