| <html> |
| |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> |
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> |
| <meta name="ProgId" content="FrontPage.Editor.Document"> |
| <title>Sleak</title> |
| </head> |
| |
| <body> |
| |
| <h3> |
| Sleak |
| </h3> |
| |
| <p> |
| <i>Sleak</i> is a simple tool that monitors SWT <i> graphics</i> resources. |
| (Applications typically don't leak <i>widget</i> resources because of rule 2). You can use |
| <i>Sleak</i> to detect leaks in SWT application code. |
| </p> |
| |
| <p> |
| Here is the source code: <a href="Sleak.java.htm">Sleak.java</a>. |
| </p> |
| |
| <p> |
| To use the tool, put the <i> Sleak</i> class on your class path and then find the place |
| in your application code where you create the <i>Display</i>: |
| </p> |
| |
| <p> |
| Display display = <b><font COLOR="#7f0055">new |
| </font></b>Display(); |
| </p> |
| |
| <p> |
| Before creating the display, create a <i>DeviceData</i> and set the <b>data.tracking</b> |
| flag to true.<br> |
| Then create the <i>Display</i> with this new <i>DeviceData</i> object.<br> |
| Then create an instance of <i>Sleak</i> and open it.<br> |
| Your new code will look something like this: |
| </p> |
| |
| <p style="margin-top: 0; margin-bottom: 0"> DeviceData data = <b><font COLOR="#7f0055">new |
| </font></b>DeviceData();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> data.tracking = <b><font COLOR="#7f0055">true</font></b>;</p> |
| <p style="margin-top: 0; margin-bottom: 0"> Display display = <b><font COLOR="#7f0055">new |
| </font></b>Display(data);</p> |
| |
| <p style="margin-top: 0; margin-bottom: 0"> Sleak sleak = <b><font SIZE="2" COLOR="#7f0055">new |
| </font></b>Sleak();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> sleak.open();</p> |
| |
| <p> |
| Now run your code as usual. When the <i>Sleak</i> window comes up, it looks like |
| this: |
| </p> |
| |
| <p style="margin-top: 0; margin-bottom: 0"> |
| <img border="0" src="sleak.1.gif" width="384" height="268"> |
| </p> |
| |
| <p>When you press the "Start" button, <i>Sleak</i> collects and |
| displays a list of the SWT graphics resources that are currently allocated. At this point, perform |
| the action in your application that you suspect is leaking. When you press the |
| "Stop" button, <i>Sleak</i> displays the list of resources |
| that were allocated since you pressed "Start". Select a resource in |
| the list on the left and it will be drawn in the canvas on the right. Select the "Stack" |
| checkbox to see a stack trace showing where the resource was created. This does not |
| necessarily imply that this resource was leaked - just that it currently exists. |
| If you believe that this particular resource is no longer needed and should have |
| been disposed, then you have discovered a leak. |
| </p> |
| |
| <h3> |
| Example |
| </h3> |
| |
| <p> |
| Look at <a href="LeakExample.java.htm">LeakExample.java</a>. You suspect that |
| this code is |
| leaking, and decide to use <i>Sleak</i> to verify your theory, and to |
| investigate a possible fix. |
| </p> |
| |
| <p> |
| Find the line of code that creates the <i>Display</i>: |
| </p> |
| |
| <p> |
| display = <b><font SIZE="2" COLOR="#7f0055">new |
| </font></b>Display(); |
| </p> |
| |
| <p> |
| And rewrite the beginning of the <b>main()</b> |
| method as follows: |
| </p> |
| |
| <p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055">public |
| static void </font></b>main(String[] args) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> DeviceData data = <b><font COLOR="#7f0055">new |
| </font></b>DeviceData();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> data.tracking = <b><font COLOR="#7f0055">true</font></b>;</p> |
| <p style="margin-top: 0; margin-bottom: 0"> display = <b><font COLOR="#7f0055">new |
| </font></b>Display(data);</p> |
| <p style="margin-top: 0; margin-bottom: 0"> Sleak sleak = <b><font COLOR="#7f0055">new |
| </font></b>Sleak();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> sleak.open();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> ...</p> |
| <p style="margin-top: 0; margin-bottom: 0">}</p> |
| |
| <p> |
| Run the <i>LeakExample</i> class as usual, and two windows open: your |
| application, and the <i>Sleak</i> window. Press <i>Sleak</i>'s "Start" |
| button, and |
| notice that no resources have yet been allocated - nothing shows up in <i>Sleak</i>'s |
| resource list. |
| </p> |
| |
| <p> |
| <img border="0" src="sleak.2.gif" width="222" height="227"> <img border="0" src="sleak.3.gif" width="222" height="227"> |
| </p> |
| |
| <p> |
| Return to the <i>LeakExample</i> window and click on an item in the list that |
| has an associated image, say, '.gif'. Press "Start" again, |
| and now you can see that one image has been created. Select the image and see |
| that it is the one currently being displayed in the example. This will be your |
| "starting point". No resources have been leaked yet because there is only one image, and it |
| is still being used. |
| </p> |
| |
| <p> |
| <img border="0" src="sleak.4.gif" width="222" height="227"> <img border="0" src="sleak.5.gif" width="222" height="227"> |
| </p> |
| |
| <p> |
| Now click on some other items in the example list, and press "Stop". <i>Sleak</i> |
| shows 2 images that were both created since "Start" was pressed, but |
| only one is being displayed in the application. |
| </p> |
| |
| <p> |
| <img border="0" src="sleak.6.gif" width="222" height="228"> <img border="0" src="sleak.8.gif" width="222" height="227"> |
| </p> |
| |
| <p> |
| Select one of the new images, and check "Stack" to see where the image was created: |
| </p> |
| |
| <p> |
| <img border="0" src="sleak.7.gif" width="587" height="228"> |
| </p> |
| |
| <p>The image was created in the <b>widgetSelected</b> method in the <i>LeakExample</i> |
| class, so this is the method to look at to see if the example is leaking. Here |
| is the code for the method: |
| </p> |
| |
| <p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055"> |
| public void </font></b>widgetSelected(SelectionEvent e) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| image = <b><font COLOR="#7f0055">null</font></b>;</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| String[] selection = list.getSelection();</p> |
| <p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055"> |
| if </font></b>(selection.length != 0) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| Program program = Program.findProgram(selection[0]);</p> |
| <p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055"> |
| if </font></b>(program != <b><font COLOR="#7f0055">null</font></b>) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| ImageData imageData = program.getImageData();</p> |
| <p style="margin-top: 0; margin-bottom: 0"><b><font COLOR="#7f0055"> |
| if </font></b>(imageData != <b><font COLOR="#7f0055">null</font></b>) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| <b><font COLOR="#7f0055">if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) |
| image.dispose();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| image = <b><font COLOR="#7f0055">new </font></b>Image(display, imageData);</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| }</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| }</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| }</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| canvas.redraw();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| }</p> |
| |
| <p>The <b>image = null</b> at the beginning of the method looks suspicious. |
| This was added so that the paint did not draw the old image if an item with no |
| image was |
| selected. Before setting <b>image</b> to null, the image should be disposed, as follows: |
| </p> |
| |
| <b> |
| <p style="margin-top: 0; margin-bottom: 0"><font COLOR="#7f0055"> |
| if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) {</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| image.dispose();</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| image = <b><font COLOR="#7f0055">null</font></b>;</p> |
| <p style="margin-top: 0; margin-bottom: 0"> |
| }</p> |
| |
| <p>After adding this dispose code, notice that you can delete the old line that |
| disposed the image right before creating a new one: |
| </p> |
| |
| <p><b><font COLOR="#7f0055"> |
| if </font></b>(image != <b><font COLOR="#7f0055">null</font></b>) image.dispose(); |
| </p> |
| |
| <p>Now the code has been cleaned up, so run it under <i>Sleak</i> again and |
| verify that nothing is leaking. One last thing for completeness and to get into |
| good habits: you should also check if <b>image</b> needs disposing after the read and |
| dispatch loop, or in a dispose listener on the shell. |
| </p> |
| |
| </body> |
| |
| </html> |