© Ioannis Kostaras, Constantin Drabo, Josh Juneau, Sven Reimers, Mario Schröder, Geertjan Wielenga 2020
I. Kostaras et al.Pro Apache NetBeanshttps://doi.org/10.1007/978-1-4842-5370-0_6

6. Debugging and Profiling

Ioannis Kostaras1 , Constantin Drabo2, Josh Juneau3, Sven Reimers4, Mario Schröder5 and Geertjan Wielenga6
(1)
The Hague, South Holland, The Netherlands
(2)
Ouagadougou, Burkina Faso
(3)
Chicago, IL, USA
(4)
Salem, Germany
(5)
Berlin, Germany
(6)
Amsterdam, The Netherlands
 

Debugging and profiling are probably the two most important things, besides writing code, for which you can use Apache NetBeans. Debugging is the art of figuring out problems and their root causes. Apache NetBeans provides a very feature-rich debugging environment from multiple sessions to multiple languages. If debugging makes your code right, profiling will make it run fast. Apache NetBeans contains one of the most advanced profiling engines for memory and CPU profiling based on the JFluid technology developed by Sun Microsystems. Although Apache NetBeans supports debugging for a lot of different programming languages and project types, this chapter focuses on support for the JVM and the Java Language.

Debugging

Getting Started

Starting a debugging session is simple. As an example, we use the Anagram Game sample provided by NetBeans. Just select New Project, go to the Samples category expand Java in the tree, and select Anagram Game in the Project list. Once you have it opened, just press the Debug Project button in the toolbar or use the menu item from the context menu of the project node. Besides just running a project in the debugger, Apache NetBeans also supports attaching a debugger to a running process. There are different attachment modes: ProcessAttach, SocketAttach, or SocketListen. Depending on the installed plugins, it will be possible to select different debuggers as well; for example, gdb if C++ plugins are available.

The dialog for attaching a debugger is shown in Figure 6-1.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig1_HTML.jpg
Figure 6-1

Attach debugger to running process

Once the debugger is running, Apache NetBeans automatically shows two additional views, the Debugging view and the Variables view. The Debugging view is used to display all threads running (or paused) in the debugged process. The Variables view displays information about variables in the actual context, once the debugger stops. An example of NetBeans showing the initial debugger experience can be seen in Figure 6-2.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig2_HTML.jpg
Figure 6-2

Initial debugging experience

Note

If any of the screenshots show windows that are not immediately visible to you, this is typically caused by window presets differing from the default (e.g., caused by usage of your IDE). To open the necessary window, just select Window from the main menu and select the corresponding item from the Debugging submenu.

In addition to the two views, Apache NetBeans shows the Debug toolbar. This toolbar provides access to all the necessary actions to control the debugging session. Besides the toolbar, all actions can also be triggered via the Debug main menu item or selected ones using the keyboard. All buttons to control the debugging workflow can be seen in Figure 6-3.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig3_HTML.jpg
Figure 6-3

Debugging toolbar

The actions from left to right are the following:
  • Finish Debugger Session (⇧-F5). Ends the debugging session by either detaching from or killing the debugged process, depending on the mode the debugger is used in.

  • Pause Debugger Session. Suspends all running threads of the debugged process.

  • Continue Debugger Session (F5). Resumes all paused threads.

  • Step over (F8). Moves the execution pointer to the next line.

  • Step over Expression (⇧-F8). Moves the execution pointer one expression further.

  • Step into (F7). Moves the execution pointer one stack-level down, that is, steps into the method call in this line. If multiple method calls are available, the exact method call can be selected.

  • Step out (+F7). Moves the execution pointer one stack-level up, that is, steps out from the actual method debugged.

  • Run to Cursor (F4). Moves the execution pointer to the line that the cursor is positioned on.

  • Apply Code Changes. Compiles the code in the active editor tab and pushes the changed code to the JVM. In addition, the execution pointer may be moved up the stack, to accommodate the new code.

  • Toggle Pause in GraalVM Script. Schedules a suspend with regard to the Truffle multi-language integration. To use this action, NetBeans must run on GraalVM.

  • Take GUI Snapshot. Takes a snapshot of the current state of the Swing component graph for interactive inspection and modification.

The last thing needed to have a real debugging session is a Breakpoint . A breakpoint defines where the debugger will automatically suspend the thread, which happens to run past the defined breakpoint. The simplest way to create a new breakpoint is to either click into the gutter of the editor on the correct line, or press ⌘-F8 (in Mac) or Ctrl+F8 (on Windows/Linux) with the cursor being on the line where the debugger should suspend the execution. The same actions can be taken to remove a breakpoint, that is, the action triggered is called Toggle Breakpoint. Once a breakpoint is created, it is marked in the gutter with a special symbol. This can be seen in Figure 6-4.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig4_HTML.jpg
Figure 6-4

Debugging toolbar

The Debugging View

Starting with the simple breakpoint shown in Figure 6-4, we start a new debugging session, and as expected, the debugger stops at line 73 in the Anagrams class. The debugging view will show by default the suspended thread with call stack information, as can be seen in Figure 6-5.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig5_HTML.jpg
Figure 6-5

Debugging view

On the bottom of the view are a couple of buttons to control the behavior of the view (options). From left to right, they are:
  • Show less. Toggles which threads are shown in the view. By default, only the suspended threads are shown, but you can toggle between all threads and suspended threads only using this button.

  • Show thread groups. Toggles the visibility of thread groups, which switches the list-style view to a tree-style view and groups the visible threads by their thread group.

  • Show suspend/resume table. Toggles the visibility of the column on the right-hand side of the view, displaying the actual state of the thread, that is, paused or running.

  • Show system threads. Toggles the visibility of system threads. By default, system threads are hidden.

  • Show monitors. Toggles the display of monitors (locks) obtained by a thread. By default, monitors are not shown.

  • Show qualified names. Toggles the display of full qualified class names. This can be helpful to identify where a specific class showing up in the displayed stack is really coming from.

  • Sort by suspended / resumed state. Toggles sort ordering of the thread list according to their state.

  • Sort by name. Toggles sort ordering of thread list according to their name.

  • Sort by default. Switches to default sort order (sorted by name).

Besides the options that are available to configure the view, the view also allows interaction with the threads. The first thing to control is thread state. By clicking on the buttons shown on the right-hand side of the view, running threads can be suspended and suspended threads can be resumed. This may be helpful once the application really requires multiple threads during debugging, and it is necessary to suspend the threads as needed to ensure correct application state. In addition, multiple threads often stop at breakpoints, which are currently not interesting (but still required to be active). Using these controls, those threads can be resumed.

Another interesting technique is to investigate the state at different frames in the call stack. The active frame is highlighted in bold (as shown in Figure 6-5) and can be changed by either double-clicking onto another stack frame entry or by using the context menu item Make Current of a stack frame.

The context menu of a stack frame has an additional interesting feature. Besides just inspecting the stack at a different frame, the menu item Pop To Here allows it to unwind the stack up to the selected stack frame. This is a nice little helper, since it allows retrying code fragments – especially if they do not modify the state.

If the context menu is invoked not directly on the call stack entries, you get some additional helper actions. Two of them are straightforward, Resume All Threads, and Suspend All Threads, but the third is more interesting. The Check for Deadlock tool is very useful for addressing tricky multi-threaded situations, where deadlocks are often difficult to detect and debug.

There is more hidden in the Debugging view, but we look into this later in the context of multi-session debugging.

Now let’s start stepping through the code. Stepping into code will take us to the WordLibrary. Apache NetBeans will automatically open a new tab to show the source code of the WorldLibary class and stops again. This situation is shown in Figure 6-6.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig6_HTML.jpg
Figure 6-6

Multiple editor tabs for debugging

Expression Evaluation

Now let’s assume we are interested in what StaticWordLibrary.DEFAULT is all about. Hovering with the mouse over DEFAULT, a tooltip shows up displaying basic information as seen in Figure 6-7.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig7_HTML.jpg
Figure 6-7

Tooltip for evaluation

If we want to know more details, just click on the little arrow in front of the text, and you will get a structured view of the object evaluated by hovering. You can drill deeper by following the displayed tree structure and can finally see the words used, as shown in Figure 6-8.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig8_HTML.jpg
Figure 6-8

Tooltip for evaluation (expanded)

This type of evaluation allows for a fast drill down into details of an object state. It can even be used to change the state. Just click in the right colum (value) for a field with a simple type, for example, String, and type a new value and hit Enter. This will change the value of the field to the entered value.

Another helpful shortcut is the possibility to highlight a piece of code and get a tooltip with the result. Step further through the code until you reach the StaticWordLibrary again and the debugger stops for you in line 147. Now select the SCRAMBLED_WORD_LIST(idx) and hover with the mouse. A tooltip shows up as can be seen in Figure 6-9.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig9_HTML.jpg
Figure 6-9

Tooltip for expression evaluation

If you look close enough, there is a pin shown before the arrow icon. Clicking the pin (symbol/icon) pins the expression evaluation into the source code. So, whenever you come back to the file, the expression is automatically reevaluated by the debugger, and the result is shown and kept current. A pinned evaluation expression is shown in Figure 6-10.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig10_HTML.jpg
Figure 6-10

Pinned expression evaluation

In addition to the expression evaluation as part of the source code editor, there is a special view, which can be opened using ⌘+F9 (on Mac) or Ctrl+F9 (on Windows/Linux) or from the main menu in the Debug menu. It displays an area where you can enter arbitrary code, which can be evaluated by either pressing CTRL-⏎ or clicking on the button on the lower-right corner. The arbitrary code example can be a complex code snippet covering multiple lines. The result of the evaluation is shown in the Variables view in Figure 6-11.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig11_HTML.jpg
Figure 6-11

Evaluate Expression and Variables view

The code editor area is aware of the actual debugging context, that is, it offers completion for visible fields and methods from the context and even supports code completion during writing code. In case you need some code snippet you already used before, there is a button in the upper-right corner showing the last-used code snippets from the Evaluate Expression view.

The code snippets evaluated cannot only be used to read data but also write changes back to the debugged application. This can be very helpful if it is necessary to change the state of a debugged application, for example, after applying a code fragment, to ensure a correct retry of the code. A complete history of the evaluated expressions can also be seen in the Evaluation Result view shown in Figure 6-12.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig12_HTML.jpg
Figure 6-12

Evaluation Result view

In contrast to the Evaluation Result view that shows multiple results all at the same time, the Variables view in Figure 6-11 shows only the latest evaluated expression on top of all other information.

Let’s have a more detailed look at this view, as shown in Figure 6-13.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig13_HTML.jpg
Figure 6-13

Variables view

Variables View

The Variables view is the place to inspect (and change) the state of all objects reached during debugging. It is split into three major areas.

First, the evaluation result of the code snippet from the Evaluate Expression view is shown (pinkish icon).

Second, there is a list of watches shown (blue icon). Watches are a kind of persistent shortcut to simple evaluation results, for example, some special field that is some levels down the hierarchy in the list of variables that can be made statically visible, despite the variable list refreshing during debugger context changes, for example, leaving a class during debugging. If you temporarily do not need the watches to be updated anymore, it is possible to disable each watch by deselecting the check box in front of the displayed watch.

Third, the list of variables, for example, this and local variables, is shown (green icon).

Like other views, the Variables view can also be customized. The customization can be done by using one of the buttons on the left-hand side of the view. From top to bottom:
  • Show Evaluation Result inside Variable View. Toggles the visibility of the result from evaluating the code snippet in the Evaluate Expression view in the Variables view.

  • Show Watches inside Variables View. Toggles the visibility of the defined watches in the Variables view.

  • Create new Watch. Opens up a dialog, which allows the user to enter an expression to be watched. The text field supports code completion to allow for a faster creation of the watch with less typing.

  • Open Formatter Options. Opens the preferences window (options window) allowing the user to define how objects of a special type will be rendered in the Variables view.

  • Show values as visual property editors, when available. If a property editor is available (registered) in the IDE for the type of the variable (field), the property editor is used for rendering / editing of the type instead of the defined formatter logic.

As an alternative, a watch can also be created by double-clicking on the label “<Enter new watch>”. The text field showing up supports code completion as well, as can be seen in Figure 6-14.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig14_HTML.jpg
Figure 6-14

Adding new watch with code completion

The context menu on the different items in the Variables view helps with further interactions:
  • Delete. Deletes a watch: either fixed, pinned, or default watch.

  • Delete All. Deletes all watches.

  • Create Fixed Watch. Creates a watch, which is not based on the actual context but on the global context.

  • Edit. Opens up a dialog, which allows changing the expression to be watched. The text field supports code completion to allow for a faster creation of the watch with less typing.

  • Show Pinned Watches. Shows all watches created by pinning down an expression evaluation in the source code view.

  • New Watch. Opens up a dialog, which allows the user to enter an expression to be watched. The text field supports code completion to allow for a faster creation of the watch with less typing.

  • Go to Type Source. Opens the source code attached to the type in an editor tab. If there is no source code available, a disassembled substitute is shown.

  • View as. Toggles the view component to use a table or a tree table for displaying the data.

  • Show references. Opens a Heap Walker view to inspect the actual reference network of the selected variable.

  • Mark Object. Attaches a label to an object to help identify that object during the further debugging process.

  • Show Only Rows where. Filters out rows from the view based on the type of the variable. Different filter types are available.

With all these possibilities, the Variables view is a very powerful tool to help you understand the state of your application. This view is accompanied in Apache NetBeans with a couple of other views that support the debugging process from different perspectives. The first one that we take a deeper look at is the Watches view.

Watches View

The Watches view is a spcialized view, which is dedicated only to the display of and interaction with the watches feature (which has already been described as part of the Variables view). An example view is shown in Figure 6-15.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig15_HTML.jpg
Figure 6-15

Watches view

The major difference to the Variables view is that the Variables view provides mixed information where the Watches view focuses solely on displaying watches. All interactions with watches described in the Variables view section are available here as well:
  • Show Pinned Watches. Shows all watches created by pinning down an expression evaluation in the source code view.

  • New Watch. Opens up a dialog, which allows the user to enter an expression to be watched. The text field supports code completion to allow for a faster creation of the watch with less typing.

  • Create fixed watch. Creates a watch, which is not based on the actual context but on the global context.

Threads View

The Threads view is a simplified version of the Debugging view. It shows all the threads of the debugged process by name in a tree view, grouped by their thread groups. An example of the view is shown in Figure 6-16.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig16_HTML.jpg
Figure 6-16

Threads view

Additional columns show a description of the thread state and if the thread is suspended by the debugger. The column showing the suspended state can also be used to suspend or resume the thread in the debugging session. Some of the interactions we already know from the Debugging view are also available as part of the context menu for thread. If we need details about the thread currently being debugged, we need to open the Call Stack view.

Call Stack View

The Call Stack view is the other half of the Debugging view as a separate view . It shows the call stack of the debugged thread and allows the same kind of interaction on the stack frames that are available in the Debugging view, that is, Make Current, Pop To Here. Typically during a debugging session, the Debugging view is sufficient for all things around thread management and control, so that the separate views for call stacks and threads are not used. The call stack display is shown in Figure 6-17.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig17_HTML.jpg
Figure 6-17

Call Stack view

A lot of the debugging features and techniques we discussed so far are centered around threading and evaluation of values. One other feature that is far less known is the possibility to do a heap walk during the debugging session. A heap walk is a debugging technique to investigate the content of the heap starting from either a single instance (as displayed in the Variables view) or a heap histogram showing how many instances (with total size) of which type (class) are part of the heap. Such a histogram can be shown by opening the Loaded Classes view.

Loaded Classes View

The Loaded Classes view displays for all loaded classes a histogram based on the number of instances of each class. This is a simple starting point for analyzing the composition of the heap. The view displays the instance number as an absolute value and as a percentage of all instances. The table is by default sorted by the absolute instance count as can be seen in Figure 6-18.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig18_HTML.jpg
Figure 6-18

Loaded Classes view

Due to the nature of such a heap histogram, the list of classes can be really long. To make a better drill down possible, a filter can be defined at the bottom of the table. There are different filter types available:
  • Contains. Shows all classes with a full qualified class name containing the filter string.

  • Does not contain. Shows all classes with a full qualified class name not containing the filter string.

  • Regular Expression. Shows all classes with a full qualified class name matching the filter string as a regular expression.

  • Subclass of. Shows all classes that are a subclass of the entered class. The class needs to be entered with the full qualified class name.

Once the filter is active, a red x is shown on the right-hand side of the filter text field. It can be used to clear the filter. On the far right-hand side is a kind of spinner control, which gives access to previously entered filter strings.

For each row displaying a class from the heap, there is a context menu with the following actions:
  • Show in Instances View. Opens the Instances view if it is closed in an editor tab and displays the instances of the selected class.

  • Show Only Subclasses. Enables the subclass filter capability based on the selected class.

  • Go to Source. Opens the source for the selected class in an editor tab. If the tab is already available, it will be activated and shown.

Trying to analyze the heap content starts with a good filter for the histogram; typically look for your own classes first and figure out what the object graph for this instance is. This analysis is done using the Instances view.

Instances View

The Instances view is at the heart of the heap analysis (heap walking). The major thing shown in this view is a list of the different instances of one class. By selecting one instance from the list in the upper-left tree, the other three components get updated. The lower-left one shows a value representation of the instance, for example, the character sequence for a String. The upper right-hand side is the structured view of the instance, that is, it allows you to view all fields with the values recursively by digging through the tree. The lower right-hand side shows where the actual instance is used. This is the reference chain, which can be followed up to figure out which object is holding onto your precious instance. All these details can be seen in Figure 6-19.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig19_HTML.jpg
Figure 6-19

Instances view

If you want to see details of an instance that is shown as part of the fields list, open the context menu and select Show Instance. This switches the Instances view to render the instance list of the same type as the selected instance in the fields list and preselects the instance in the instances list. This allows for a quick drill into the hierarchy of objects.

Now that we already know how to deal with threads, memory, and evaluations in Apache NetBeans during debugging sessions, we still need to figure out how to deal with breakpoints.

Breakpoints

Breakpoints are a crucial feature for debugging, because they allow to stop the debugged process at arbitrary places in the code. Breakpoints in Apache NetBeans can be managed and displayed across source files using the Breakpoints view. Besides viewing breakpoints as an unstructured list, breakpoints can be grouped into custom or predefined, for example, by programming language, Breakpoint Groups. One breakpoint can belong to one custom group and can be moved from one group to another if needed. Before we dive deeper into those details, let’s start with creating some new breakpoints.

There are different ways to create a breakpoint in Apache NetBeans:
  • By toggling a breakpoint in the gutter (the area where the line numbers are displayed) will create or delete a Class Breakpoint, Field Breakpoint, Line Breakpoint, or Method Breakpoint

  • By using the menu item New Breakpoint (⇧-⌘-F8 on Mac or Ctrl+Shift+F8 on Windows/Linux) from the Debug menu in the main menu, all types of breakpoints can be created.

Creating a new breakpoint using the New Breakpoint action allows a complete configuration of a breakpoint at creation time. The first step is the selection of the debugger, which in turn changes the list of breakpoint types available. For the Java debugger, the breakpoint types are the following:
  • Class. Stops the debugged process based on class states.

  • Exception. Stops the debugged process based on exceptions thrown.

  • Field. Stops the debugged process if a field is accessed.

  • Line. Stops the debugged process if special line in a file is reached.

  • Method. Stops the debugged process on method-related states.

  • Thread. Stops the debugged process on thread-related states.

  • AWT/Swing Component. Stops the debugged process on component-related events.

All breakpoint types allow for additional properties to be configured. They are grouped into two categories, Conditions and Actions, and may differ between breakpoint types. The New Breakpoint dialog is shown in Figure 6-20.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig20_HTML.jpg
Figure 6-20

New Breakpoint dialog

The Actions properties describe what happens once a breakpoint is reached. There are four different actions associated with every breakpoint type.
  • Suspend. Allows the selection of which threads will be suspended if the breakpoint is reached. Possible values are Breakpoint Thread (the thread on which the breakpoint was reached), All threads, or No thread (continue). Selecting No thread will only print the text under the action Print Text but not stop any threads. This is helpful if only a list of values at different points is required, but no further interaction with the debugged process is needed, for example, in a multi-threaded application where stopping threads will change runtime behavior.

  • Enable Group. Enables the selected group of breakpoints once this breakpoint is reached. Together with the next action, this enables some kind of automated context-based breakpoint control, to reduce the effort to manually enable or disable breakpoints in special areas of the code.

  • Disable Group. Disables the selected group of breakpoints once this breakpoint is reached. Together with the previous action, this enables some kind of automated context-based breakpoint control, to reduce the effort to manually enable or disable breakpoints in special areas of the code.

  • Print Text. Prints the configure text to the debugger console, once the breakpoint is reached.

Printing text once a breakpoint is reached uses a special syntax for dynamic information. Dynamic information is guarded by {}, while everything outside is just plain text. The following dynamic syntaxes are supported:
  • {=<expression>}. Prints the result of the evaluation of the expression (see above) based on the context at the reached breakpoint;

  • {className}. Prints the name of the class, in which the breakpoint was defined;

  • {exceptionClass}. Prints the name of the exception class with regard to the breakpoint definition;

  • {exceptionMessage}. Prints the message of the exception with regard to the breakpoint definition;

  • {fieldName}. Prints the actual name of the field, in which the breakpoint was defined;

  • {lineNumber}. Prints the actual line number;

  • {methodName}. Prints the actual name of the method, in which the breakpoint was defined;

  • {threadName}. Prints the name of the thread, on which the breakpoint was reached;

  • {? threadStarted}{}{}. Prints either the text in the first or in the second group, depending on the state of threadStarted. Both groups can contain dynamic syntax elements.

Not all of those dynamic elements are available for all breakpoint types, for example, threadStarted. An example text is prefilled in the Print Text action text field.

The Conditions, describing the constraints the debugger considers for stopping at a reached breakpoint, are not the same for all breakpoint types, but most breakpoint types adhere to the following two constraints:
  • Condition. Describes an expression (see evaluation) that must evaluate to true for the debugger to stop.

  • Break when hit count is. Describes how often the breakpoint must be hit to make the debugger stop.

There are different comparators available for the hit count:
  • Equal to. The hit count must be equal to the defined value for the debugger to stop.

  • Greater than. The hit count must be greater than the defined value for the debugger to stop.

  • Multiple of. The hit count must be a multiple of the defined value for the debugger to stop.

The full generic Conditions can be seen in Figure 6-21.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig21_HTML.jpg
Figure 6-21

Generic Breakpoint conditions

The Settings, describing the setup of the breakpoint type, are different for every breakpoint type so let’s go through them one by one.

Class Breakpoints

A Class Breakpoint is defined by a full qualified class name and the state of the class from the class loader perspective, which is observed by the debugger:
  • Class Load. Debugger stops during class loading.

  • Class Unload. Debugger stops during class unloading.

  • Class Load or Unload. Debugger stops during class loading and unloading.

The Settings configuration of the Class Breakpoint can be seen in Figure 6-22.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig22_HTML.jpg
Figure 6-22

Class Breakpoint settings

Exception Breakpoints

An Exception Breakpoint stops in case of a thrown exception. It is defined by a full qualified exception class name and the state of the exception as observed by the debugger:
  • Caught. Stops only if the exception is caught.

  • Uncaught. Stops only if the exception is not caught.

  • Caught or Uncaught. Stops in both cases.

The Settings configuration of the Exception Breakpoint can be seen in Figure 6-23.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig23_HTML.jpg
Figure 6-23

Exception Breakpoint settings

Because the more interesting cases for configuring the breakpoint behavior of an Exception Breakpoint are not defined by the exception class, the Conditions of such an exception have an additional customization option:
  • Filter on Classes throwing the Exception. Restricts the breakpoint to specific classes throwing the specified exception. Class names for Match Classes and Exclude Classes have to be specified full qualified, but an asterisk can be used at the end as a wildcard. Multiple patterns can be specified by separating these by commas.

The Conditions configuration of the Thread Breakpoint can be seen in Figure 6-24.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig24_HTML.jpg
Figure 6-24

Exception Breakpoint conditions

Field Breakpoints

A Field Breakpoint stops the debugged process if a field of a defined class is accessed. It is defined by a full qualified class name and respective field name and selecting in which access cases the debugger will stop:
  • Field Access. Stops if the field is accessed, for example, read access.

  • Field Modification. Stops if the field is written to.

  • Field Access or Modification. Stops if the field is accessed or written to.

The Settings configuration of the Field Breakpoint can be seen in Figure 6-25.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig25_HTML.jpg
Figure 6-25

Field Breakpoint settings

Line Breakpoints

A Line Breakpoint is defined by a line in a source code file, which points to an executable line of code, that is, not a class, method, or field declaration. The source code file is referenced as an absolute path.

The Settings configuration of the Line Breakpoint can be seen in Figure 6-26.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig26_HTML.jpg
Figure 6-26

Line Breakpoint settings

Method Breakpoints

A Method Breakpoint is defined by a full qualified class name and a method specification, either a concrete method name or all methods of the defined class. In addition, it is required to specify when to stop:
  • Method Entry. Stops before entering the method.

  • Method Exit. Stops before exiting the method.

  • Method Entry and Exit. Stops before entering and before exiting the method.

The Settings configuration of the Method Breakpoint can be seen in Figure 6-27.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig27_HTML.jpg
Figure 6-27

Method Breakpoint settings

Thread Breakpoints

Due to the nature of a Thread Breakpoint, there are only limited configuration options available. It can be defined when to stop:
  • Thread Start. Stops if a new thread is started.

  • Thread Death. Stops if a thread dies.

  • Thread Start or Death. Stops on new thread starts and thread deaths.

The Settings configuration of the Thread Breakpoint can be seen in Figure 6-28.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig28_HTML.jpg
Figure 6-28

Thread Breakpoint settings

The only condition that is usable for a Thread Breakpoint is the hit count. If you use this option, you will only get a stopped debugger for every hit count creations and or deaths of a thread. The Conditions configuration of the Thread Breakpoint can be seen in Figure 6-29.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig29_HTML.jpg
Figure 6-29

Thread Breakpoint settings

AWT/Swing Component Breakpoints

The AWT/Swing Component Breakpoint can only be defined if a snapshot of the UI has been taken (see Visual Swing Debugging, later in this chapter, for further details). If an editor tab is active, it is possible to select one component and create a new breakpoint. The component name cannot be manually entered, but is based on the selection in the UI snapshot. There are three possible ways to stop the debugger with regard to the component:
  • Add/remove from container. Stops if the component is removed or added.

  • Show/hide. Stops if the component is shown or hidden.

  • Repaint. Stops on repainting the component.

The Settings configuration of the AWT/Swing Component Breakpoint can be seen in Figure 6-30.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig30_HTML.jpg
Figure 6-30

AWT/Swing Components Breakpoint settings

All the listed breakpoints are shown in a tabular view in the Breakpoints view.

Breakpoints View

The Breakpoints view is the central view to manage and view all defined breakpoints. Different breakpoint types may be indicated with different icons. All breakpoints can be enabled or disabled by using a check box. In addition, the tabular view renders information about the defined breakpoint, for example, the line number and source file or exception class. In a column hidden by default, the actual hit count of a breakpoint can be shown. A context menu is available on every breakpoint with the following actions:
  • Go to Source. Opens the source code associated with the breakpoint in the editor area. If no source code is available, a disassembled substitute is shown instead.

  • Enable/Disable. Toggles the state of the breakpoint from enabled to disabled or vice versa.

  • Move Into Group. Moves the selected breakpoint into a breakpoint group, allowing finer-grained control with regard to enabling, disabling, or deletion.

  • New Breakpoint. Opens the dialog to create a new breakpoint.

  • Enable All. Enables all breakpoints. Only active if at least one breakpoint can be enabled.

  • Disable All. Disables all breakpoints. Only active if at least one breakpoint can be disabled.

  • Delete. Deletes the breakpoint.

  • Delete All. Deletes all breakpoints.

  • Properties. Shows the properties of the breakpoint to allow inspection and changing of the Settings, Conditions, and Actions.

As shown in Figure 6-31, breakpoints that belong to a special group are shown below those groups in a tree-like manner. The context menu on a breakpoint group contains the following actions:
  • Rename Group. Renames the breakpoint group.

  • Enable All Grouped. Enables all breakpoints in the group.

  • Disable All Grouped. Disables all breakpoints in the group.

  • Delete All Grouped. Deletes all breakpoints in the group, effectively deleting the group as well.

Besides the tabular view, there is a small toolbar on the left-hand side offering three actions:
  • Create new Breakpoint. Opens the dialog to create a new breakpoint.

  • Deactivate all breakpoints in current session. Deactivates all breakpoints in the current debugging session.

  • Select breakpoint groups. Shows a list of possible grouping strategies for the breakpoints in the list, based on custom groups or a selection of predefined groups.

../images/479166_1_En_6_Chapter/479166_1_En_6_Fig31_HTML.jpg
Figure 6-31

Breakpoints view

Visual Swing Debugging

Apache NetBeans has an additional feature for supporting debugging of a Swing application. If the debugged process has a Swing UI, it is possible to snapshot the actual component hierarchy to inspect it in a visual manner. There is a special button in the debug toolbar that triggers the snapshot and opens a Snapshot Editor tab, which can be seen in Figure 6-32.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig32_HTML.jpg
Figure 6-32

Snapshot of Swing

The snapshot allows you to select the different components, for example, buttons or text fields, and inspect their field attributes. If a property is writable, it is possible to change the value by entering a new value in the property editor in the Properties view. The context menu of the components shown in the snapshot has some very helpful actions:
  • Go To Component Declaration. Opens the relevant source code at the line where the selected component is declared. This is not the line where the component is created, but rather the line of the field definition.

  • Go To Component Source. Opens the source code file in an editor tab, which defines the component, for example, for JButton it opens the javax.swing.JButton source file (if source is available).

  • Show Listeners. Opens a new view called Events view. The events view shows registered listeners, allows navigation to source code, and displays a log of events (if configured).

  • Create Fixed Watch. Creates a fixed watch for this component.

  • Toggle Component Breakpoint. Creates a component breakpoint based on visual selection (for details regarding breakpoints, please refer to the breakpoints section).

  • Breakpoint Properties. Opens a dialog to show the properties of the component breakpoint and allow changes to the properties.

  • Properties. Opens a standalone dialog showing the property sheet associated with the selected component.

The Event view shows additional logical information based on the selected component in the Snapshot or Navigator view. The first row identifies the selected component, followed by two groups of listeners; the first group shows all custom listeners, that is, a listener not added by the UI toolkit itself, but by user code. The second group lists all listeners added from the UI toolkit itself. The last section in the list of information is the Event Log. It shows a list of events issued by the component. This helps in better understanding the behavior in terms of events triggered and reactions of the component hierarchy. If you need to debug the Swing component hierarchy behavior, this type of debugging reduces the amount of setup you need to do yourself and gives you direct and simple access to the internals of Swing. An example view can be seen in Figure 6-33.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig33_HTML.jpg
Figure 6-33

Event view showing listeners and event log

For the entries in the Event Log section to show up, it is necessary to configure some type of listener to be selected for logging. This can be done using the context menu Setup Logging Events of the Event Log item. It will open a dialog showing the possible listeners. All listeners selected will lead to entries in the Event Log, if events are sent to those types. The list of listeners is shown in Figure 6-34.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig34_HTML.jpg
Figure 6-34

Select events for logging

The context menu item Clear on the Log Event item can be used to clear the current list of log entries.

While being in active GUI snapshot mode, the navigator displays the Swing component hierarchy, identifying each component with their respective variable name, if the name can be derived. In addition, a textual representation of the component is rendered to help identify the component in the snapshot view, for example, the text shown in a label or button. The actions that can be performed are the same as on the selected component in the UI snapshot. An example Swing hierarchy based on the Anagram Game can be seen in Figure 6-35.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig35_HTML.jpg
Figure 6-35

Swing Hierarchy in Navigator view

Selecting a component in the navigator view highlights the component in the Snapshot Editor tab, which helps identifying a component in the visual Snapshot view. The selection also changes the content of the Properties view to display the properties of the component selected in the Navigator view.

Multi-Session Debugging

The Apache NetBeans debugger supports having multiple debugging sessions running at the same time. This is very helpful if you have to debug, for example, some integration issue between the Java front end and back end, and you can simultaneously debug both processes. The debugger seamlessly integrates the multi-session capabilities into the default views and workflows. In the Debugging view, an additional combo box is shown, allowing you to select the debugging session the threads are shown for, as in Figure 6-36.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig36_HTML.jpg
Figure 6-36

Session selection in Debugging view

In addition to enhancing the Debugging view with necessary information for the multi-session workflow, there is a dedicated Sessions view showing all debugging sessions, with their state, programming language, and the host they are executed on (remember debugging sessions could be running attached to a process on a remote host). There is a context menu on every session providing interaction with the sessions:
  • Make Current. Toggle the debugger to actively debug this session.

  • Scope. Selects if all threads or just the current thread should be debugged.

  • Language. Selects the debugger to use for this process, in case multiples may be applicable.

  • Finish. Finishes the debugging session.

  • Finish All. Finishes all debugging sessions.

An example of the Sessions view showing two processes is shown in Figure 6-37.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig37_HTML.jpg
Figure 6-37

Sessions view

Profiling

Getting Started

Starting a profiling session for a project opened in Apache NetBeans is not as simple as debugging, because it requires more setup decisions. So let’s walk through the process of starting a profiling session (as an example, we will just use the Anagram Game sample from Apache NetBeans). If the project is already open, select the project node in the Projects view and press the Profile Project button in the toolbar. The first step you now need to take is the configuration of your profiling session. This has to be done, because the Apache NetBeans Profiler supports multiple profiling modes:
  • Telemetry. Monitors CPU and Memory usage, number of threads, and loaded classes.

  • Methods. Profiles method execution times and invocation counts, including call trees.

  • Objects. Profiles size and count of allocated objects, including allocation paths and generational count.

  • Threads. Monitors thread states and times.

  • Locks. Collects lock contention statistics.

  • SQL Queries. Display executed SQL Queries, their duration, and invocation paths.

There is a more complex setup for profiling a remote VM, which requires setting up the remote JVM with a special agent.

We will now have a deeper look into all of the profiling modes, but first some basics.

Basic Profiling Actions

During profiling an application, there is a set of generic actions, which can always be triggered to support the profiling process. The actions are available at the right end of the profiling toolbar labeled with Process.
  • Take thread dump from profiled process. Takes a thread dump from the profiled process and opens it in a Thread Dump view.

  • Take heap dump from profiled process. Takes a heap dump from the profiled process and opens it in a Heap Walker view (see Heap Walker later in this chapter).

  • Request garbage collection in the profiled process. Requests an explicit garbage collection to be run in the profiled process. This can be used to ensure that heap dumps are not polluted with too many objects, which are not live anymore.

Telemetry

Telemetry is a very basic profiling mode. It allows us to track the following:
  • CPU load differentiated between real CPU time and time consumed by GC.

  • Heap size and used heap.

  • Key garbage collection parameters, for example, surviving generations (an ever-increasing number indicates either a cache or a memory leak) and GC intervals.

  • Threads and loaded classes.

For each of the above bullets, there is a special graph shown in the telemetry view as seen in Figure 6-38.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig38_HTML.jpg
Figure 6-38

Telemetry view

Methods

Methods profiling or execution profiling is a tool to help understand the runtime execution performance of an application. If a request to a server takes too long, an execution profiling of the application may help to figure out the bottleneck (there are other techniques, but these can be studied in deeper detail in a performance tuning handbook).

Starting the profiling session with methods will open a view similar to the one shown in Figure 6-39.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig39_HTML.jpg
Figure 6-39

Methods view live

The view as shown has two parts, which are live updated. The first is a thread view, showing where in a special thread most of the time is consumed. The second (shown at the bottom) is a view displaying the hot spots of the application in terms of which methods have been executed, how often, and how long were they running on the CPU. This can give a live impression on what is going in the application. Because a lot of threads may be running and metrics for thousands of methods will be generated, both views can be filtered either by thread name or by class name for the method view. To open the filter bar at the bottom of the view, click Filter in the context menu of the view. The filter allows for different type of matches:
  • Contains. Shows all classes with a fully qualified class name containing the filter string.

  • Does not contain. Shows all classes with a fully qualified class name not containing the filter string.

  • Regular Expression. Shows all classes with a fully qualified class name matching the filter string as a regular expression.

In addition to these filter expressions, there are predefined filters available:
  • JPA

  • JavaEE

  • JavaEE Servers

  • Java Reflection

  • Java SE

Because of the overhead Methods profiling introduces overhead into the profiled application, it is very important to configure the methods to be profiled. This can be done using the gear icon in the upper right-hand corner. This opens up a configuration area that allows us to select which methods will be instrumented for methods profiling. The default configuration is shown in Figure 6-40.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig40_HTML.jpg
Figure 6-40

Methods configuration

The default configuration is just using a sampling profiling technique for methods profiling. It is less overhead compared to the instrumented profiling, but it not very exact. The configuration differentiates between different sets of classes or methods. The most important mode due to overhead is Defined classes. This allows for an explicit selection of which classes are of interest for the profiling session as can be seen in Figure 6-41.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig41_HTML.jpg
Figure 6-41

Methods profile defined classes only

There is even the possibility to inhibit profiling of the whole tree by using the exclude outgoing calls option. Having set up all this and having followed the live results, you want to have a more detailed look at what is really happening. You can do this by creating a result snapshot from the toolbar, which opens a separate tab for the snapshot. The result view shown is not very different to the live view, as can be seen in Figure 6-42.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig42_HTML.jpg
Figure 6-42

Methods Result Snapshot

In the live view of the Methods profiling, another nice feature is available. Using a button in the toolbar, you can switch the live view to display delta values, that is, all absolute values are used as the baseline and only changes compared to this baseline are displayed, so only methods executed after triggering the delta mechanism will show up with values larger than 0 in the views. This can be used to get rid of the start-up overhead in the analyzed data.

Objects

Objects profiling is a tool to help with the analysis of memory allocation and consumption. If we are looking at memory, we typically talk about the Java heap, that is, objects allocated on the heap. Starting the profiling session in the Objects profiling mode will open a live view showing a histogram of all class instances (objects). The tabular view shows the full qualified class names, the estimated live bytes consumed by this class’s instances on the heap, and a count of live objects on the heap per class. The view has the same filtering options described for the Methods profiling. An example view is shown in Figure 6-43.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig43_HTML.jpg
Figure 6-43

Objects View live

Similar to the Methods profiling, the Objects profiling can be configured with regard to which class instances shall be tracked by the profiler. It is possible to use a sampling profiling mode here as well, which just takes samples from the heap at defined intervals. However, in this mode the profiler may miss many allocations if they die fast enough, that is, allocation and garbage collection happen in between two samples. The possible configuration types that can be selected are shown in Figure 6-44.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig44_HTML.jpg
Figure 6-44

Objects configuration

The default configuration is to use a low overhead sampling for all classes. This may be appropriate if you do not have any clue where a memory problem is originating. Using a sampling mode only for project classes reduces the amount of tracked information and puts a focus onto your own domain code. Since this may not be enough, for example, imagine a leak caused by caching instances of core Java classes, the Apache NetBeans Profiler offers two instrumented profiling modes in addition to the sampling mode. Let’s first take a look at the Defined classes mode. It allows us to specify a list of classes to be profiled by using fully qualified class names. If you need to profile all classes from a package or package tree, you can use an asterisk or a double asterisk as wildcards for those use cases. Once you have added what you need to the list (one pattern per line), there are two more options to pick from
  • Track only live objects. Defines whether only live objects or also already created objects (including released ones) are profiled.

  • Limit allocations depth. Defines the depth of the stack that is recorded for allocations. If unchecked, always the full stack is recorded, or else only the top number of stack frames are stored for anaylsis. This setting has a major impact on the overhead introduced to the target VM during profiling.

The updated configuration needs to be applied, which triggers an update to the instrumentation of the target VM. The configuration UI is shown in Figure 6-45.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig45_HTML.jpg
Figure 6-45

Objects defined

The other mode for defining the classes profiled for allocation is Selected classes. It is very similar to the Defined classes mode, besides the fact that classes for profiling are not defined by a pattern, but are selected from projects or jar files by selecting them explicitly using a simple UI. To start the selection process, you need to click the add button as shown in Figure 6-46.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig46_HTML.jpg
Figure 6-46

Objects selected

The add button opens a new dialog, allowing you to select classes from projects, which are opened in the IDE. The dialog consists of three lists (Projects, Packages, and Classes), which can all be filtered for faster access to the specific items. The content of the Packages list can be switched to contain the packages from the projects and or contain the packages from dependencies (the two toggle buttons below the list view). The Classes list shows the classes from the selected package. This list can also show inner classes and anonymous classes for selection (using the toggle buttons below the list view). The full UI is shown in Figure 6-47.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig47_HTML.jpg
Figure 6-47

Objects selected from projects

The dialog can be switched from the project-based selection to a jar file based selection of classes. Files/Folders to use can be added or removed using the buttons below the Files list, which displays the actual list of files and folders used. The Packages and Classes list work similar to the project-based selection list, as can be seen in Figure 6-48.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig48_HTML.jpg
Figure 6-48

Objects selected from jars

Using the live results is very powerful, for example, by making use of the delta mode by using the toolbar to switch the view to Show absolute values. This is similar to what is available for the Methods profiling, but even more useful for the profiling of the heap. The values shown depict the change in memory consumption starting with the moment of toggling the view. This opens the opportunity to baseline the actual memory consumption and just follow what happens in terms of memory allocation during execution of a special part of your application code. The live result shown in Figure 6-49 depicts the additional power of an instrumented profiling session compared to the sampling mode, for example, a generational count is available on the right-hand side.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig49_HTML.jpg
Figure 6-49

Objects live view with instrumentation

Below the statistics line for every class, the recorded allocation stack traces can be shown by extending the tree view using the small arrows in front of every class name. The view will show a merged reverse stack trace tree, which shows how many instances have been allocated through which code path. This is crucial information for figuring out the culprit of a memory leak. An example of such a tree is shown in Figure 6-50.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig50_HTML.jpg
Figure 6-50

Objects live view with allocation back traces

Besides the live results, it is possible to create a result snapshot of the current Objects profiling session by using the using the toolbar action Take snapshot of collected results. This allows us to store the results for later consumption or comparison with other snapshots taken. An example snapshot view is shown in Figure 6-51.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig51_HTML.jpg
Figure 6-51

Objects Snapshot Result

Threads and Locks

Threads and Locks profiling gives a more in-depth view on how your application code is really executed. Both modes together, combined by using the Enable Multiple Modes setting in the Profile drop-down menu, allow for analysis, if your code is really running on the CPU or is blocked by waiting for locks or other resources, for example, synchronous I/O.

The Threads view shows a filterable list (see Methods section above for handling of the filter mechanism) with colored coded thread states. This allows us to see live feedback on how your application is using threads and if threads are really running or just blocked, for example, for a long time or frequently for a short time. A simple example of a live Threads view is shown in Figure 6-52.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig52_HTML.jpg
Figure 6-52

Threads live view

In contrast to the Methods and Objects profiling modes, the Threads mode does not offer a result snapshot feature. Now that you have seen threads being blocked from execution, the question is what blocks them from execution. The answer to this question can be given by activating Locks profiling. The Locks view gives a detailed view of why which thread has been blocked and for how long. A very simple example is shown in Figure 6-53.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig53_HTML.jpg
Figure 6-53

Locks live view

SQL Queries

Profiling SQL Queries is just an additional layer of sugar. SQL profiling analyses of your application’s SQL queries collects the traces and execution times of the statements. It can also track the establishing of connections to the database, which may be useful in tuning your connection pool.

Heap Walker

The Heap Walker is a tool set for analyzing heap dumps taken with the OpenJDK internal heap dump mechanism (can also be triggered using some actions during profiling). It is a very thorough analysis tool with lots of capabilities for dissecting the heap dump.

First there is a Summary available showing relevant data concerning the heap dump in multiple categories:
  • Basic Info. Displays basic information, for example, file size, date of dump.

  • Environment. Displays information about the environment; where the snapshot was taken on, for example, operating system; JVM details as vendor and version.

  • System properties. Shows all system properties of the dumped JVM. The properties are shown inlined in the actual section of the view.

  • Threads at the heap dump. Shows a thread dump taken together with the heap dump. The thread dump is shown inlined in the actual section of the view.

  • Application windows. Lists all top-level Swing windows, with direct access to the instance in the Instances view.

  • Biggest Objects. Triggers the determination of the biggest objects on the heap, based on the retained sizes of its object tree, that is, everything belonging to the object. This operation may take some time, due to the need for the calculation of the retained size of all objects in the dump.

An example of the Summary view is shown in Figure 6-54.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig54_HTML.jpg
Figure 6-54

Heap Walker Summary

The next view is the Classes view. It displays the histogram of instances of classes on the heap. The tabular view can be sorted by instances, size, or name of the class. A filter at the bottom of the view allows for a faster drill down, for example, just looking for instances of your domain classes not JDK core classes. There is an initial hidden column, which would display the retained size. As already described, the computation can be a lengthy operation, so this column is hidden by default, although the information is sometimes really helpful. A simple example is shown in Figure 6-55.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig55_HTML.jpg
Figure 6-55

Heap Walker Classes

Besides the statistical analysis, there is one interesting action associated with this view – Compare with another heap dump . It opens a dialog to let you select another heap dump, either already loaded or from a file. If you are profiling a project, the dialog automatically detects comparable dumps; if you load them from file, you need to take care of that for yourself. The loading UI is shown in Figure 6-56.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig56_HTML.jpg
Figure 6-56

Heap Walker Load Comparison Heap Dump

Once the dump is loaded, the view switches to a delta comparison view telling how many more or less instances of a class have been found in the comparison heap dump. If you are done analyzing the difference, there is the possibility to reset the view to the original state. A simple comparison is shown in Figure 6-57.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig57_HTML.jpg
Figure 6-57

Heap Walker Classes Comparison

Double-clicking on a class in the Classes view opens the Instances view showing a list of all instances of this class. The view is practically identical to the Instances view described in the Debugger section. The upper-left corner shows the instances available (grouped if there are too many for a flat list), the lower-left corner shows a value representation of the object instance if possible. On the right-hand side the structure of the selected instance is shown in the Fields view and below this is the References view showing the reference chain of this instance up to the garbage collection root, which keeps the instance alive on the heap. This is critical information if a memory leak appears and it is not quite clear, why some instance will not get garbage collected, for example, some static field holding a strong reference to the instance. An example showing a profiling result in the Instances view can be found in Figure 6-58.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig58_HTML.jpg
Figure 6-58

Heap Walker Instances

The final view is the OQL Console. This view allows you to do an interactive analysis using a special OQL syntax for querying the heap. There are some queries as examples already available on the lower right-hand side in the Saved Queries view. The Query Editor on the lower right offers code completion to simplify creating new queries, which can be saved for later reusage. Once you execute a query, the result will be shown in the Query Results view, the upper half of the OQL Console view . The result of a query is always a list of instances, which can be selected and analyzed in the Instances view. The usage of the OQL Console is especially interesting if there are a lot of instances of the same object and you want to figure out a subset of those, for example, all empty maps. An example session with the OQL Console is shown in Figure 6-59.
../images/479166_1_En_6_Chapter/479166_1_En_6_Fig59_HTML.jpg
Figure 6-59

Heap Walker OQL

Summary

In this chapter we had a detailed look at two of the Apache NetBeans crown jewels, Debugging and Profiling.

You have learned how to use the debugger to tackle issues in your application code, debug multi-threaded applications, and interact with your application from the debugger.

In case of performance problems, we showed you how to profile your application to understand the underlying memory allocation and execution performance behavior. We introduced you to the built-in features, which help you analyze the data collected during the profiling runs.

Both of the features shown in this chapter are easy to use and should be part of your developer tool belt. Now we will move on to Part II, “Extending Apache NetBeans.”

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.22.107