Professional Documents
Culture Documents
drill into your programs use of temporary objects to identify problems and
preventing the memory leaks that you see in C++. But if you dont understand
the Java compilers and Java runtime environments use memory would be
object optimization.
CompuwareCorporation
Temporary objects
What, exactly, are temporary objects? These are objects that are not
persistent, are generally used from very short to medium lengths of time,
and are typically used for short or intermediate storage within the application
at runtime. The Java compiler can also create temporary objects as part of
compiler optimization.
For example, each time your application works with objects, the Java
compilers could potentially perform some optimization. The compiler can use
temporary memory space to manipulate and complete Java statements. These
objects are created and released immediately by the Java compiler on behalf
of the application without having to be explicitly defined by the engineer.
java.lang.String:
r = r + compute(i);
return r;
For all iterations, a new String r is allocated as a temporary object and the
current r is copied into that new instance, after which compute(i) is
added to the new r string. This is done each time through the above loop.
Line 3 in this example would get flagged as a cause of excessive temporary
objects. Heres how to resolve this simple problem:
2
java.lang.StringBuffer:
r.append(compute(i));
return r.toString();
The garbage collector, which manages this shared JVM heap, automatically
monitors objects and frees those that are no longer referenced by the
program. The garbage collector also has house-cleaning duties to fight heap
fragmentation that occurs as a natural effect of creation and destruction of
objects with different sizes during the course of a running program.
With simple programs or enough time and skill, you can identify object use
and its effect on the garbage collector to create better-performing applications
that require less memory at runtime. You must map all object graphs over the
applications life or even for a short moment in the applications runtime.
This task is slow and difficult.
The application engineer must know which entry point, class and method
has created each object and must determine the object size. Additionally,
the engineer needs to know which entry points, methods, threads and other
objects still hold references to each and every object in memory now and in
the past. The correlated information of object details is called the object
graph. The object graph is the map of how objects are related, where
references are held and for how long.
Getting the object graph with the size and number of object instances would
provide most of the information necessary to resolve any problems with object
use efficiency.
You could use these methods to determine the approximate size of an object
by setting up an isolated environment test:
3. Create an instance of the class you want to measure and hold a reference
to it.
4
5. Measure the free heap space once again with the Runtime.freeSpace
method.
6. The difference between the first measurement and the second is the size
of the object in question.
This would work well if you have a small application with a limited scope
to analyze. However, there are some problems that give rise to less-than-
accurate results:
5
Expert help for all usersDevPartner
Most commercial or open-source Java tools for memory analysis typically are
for use by more senior Java engineers. DevPartner Java Edition differs in
that it helps engineers of all skill levels to be more productive sooner. It helps
you analyze temporary object use and assists in resolving issues with
application efficiency.
6
With DevPartner Java Edition, you can view memory analysis in real time
as in Figure 1. Viewing frequent spikes would suggest many temporary, short-
lived objects and an area for possible improvements in efficiency. DPJ does
not just present raw collected memory analysis data, but presents what the
information means and helps isolate problems faster.
DPJs memory analysis window quickly displays descriptions for each and every
view, with an explanation of the concepts being presented and suggestions of
what to pursue next. Highlighted areas indicate the inline help (in the left-
hand column), which is customized for each user through DPJ preferences.
The ability to turn inline help off and on is helpful to junior engineers, or
those engineers simply wanting a quick refresher on the details of how to
solve performance and memory issues.
The window in Figure 2 shows the choices available and quick explanations
to help the user focus on problem areas. Notice the Run Garbage Collection
button and the corresponding heap drop in the graph after clicking on that
button. Also notice the Clear Collected Data button in the upper-left
corner. This clears all the statistics collected up until this point and provides
a view of only recent temporary objects. Both features clear out data not
relevant to your problem analysis, reducing the amount of information you
need to analyze.
7
Whats not relevant? The application server startup time and application
initialization time, for example. You need to get to a steady run state before
getting the memory analysis details that are not related to the average runtime
and scalability impacts.
Selecting View Temporary Objects... from the upper-left corner (see Figure
3) produces a second browser window with the results of the then-current
statistics of temporary object use. Notice again that the inline help is available
to explain what is being viewed, and the user does not have to go through
separate help screens or to a different path of screens.
When your code executes in a container, or has a lot of calls into it from
system code (such as Swing code), DPJ provides views that start from these
entry points into your code as well as all the underlying Java runtime
methods. This makes it easier to analyze separate paths in your code. This is
not available from any DPJ competitor, and it proves helpful when there are
multiple entry points for items like JSPs, running different methods from your
threads, applets and servlets.
8
Figure 4. DPJ detail popup.
Hovering over or selecting any element of the graph, entry point name or
method name provides more information on that specific item. Figure 4
shows the entry point information to a small application created to highlight
temporary objects for this papers example. From here, the user can go directly
to the call graph or view the source for further analysis.
Object allocations done by your code can be categorized based on how long
it takes for the objects to be collected. The three categories are short-lived,
medium-lived and long-lived. Because long-lived objects are rarely a problem,
a temporary object categorythe sum of the short-lived and medium-lived
object allocationsalso is provided.
9
Long-lived objects are in use for a long time, such as user interface widgets or
application scope JSP beans. Generally, these would be objects that live until
the application or the Java runtime environment exits. Although these can
be problems for memory footprint and scalability, they are not temporary
objects or part of this example.
DevPartner Java Edition allows you to drill into your programs use of
temporary objects to identify problems and improve the overall quality of
your code. For an in-depth description of temporary objects and their impact
on memory usage and performance, refer to Chapter 7 of Java Platform
Performance by Steve Wilson (Sun Press): http://java.sun.com/docs/books/
performance/1st_edition/html/JPMutability.fm.html#19273.
So what does DPJ provide? It gives you the ability to see which temporary
objects came and went immediately (short-lived), which objects hung around
for a bit longer (medium-lived) and which objects hung around for the life of
the method or application (long-lived).
Look at your application profile with DPJ. If DPJ identifies temporary objects
that negatively impact application performance, there are several possible
solutions depending upon what types of temporary objects and usage are
identified. Java compiler optimization can cause the creation of temporary
objects, which can be explicitly defined and de-referenced within the
application source code. Thus, the same explicitly defined objects can be
reused multiple times without the constant overhead of calling the new
constructor. Reviewing your design may show whether you can reduce
frequent use of short-lived objects by reusing the same objects for multipurpose
workspace objects, therefore reducing the creation and de-referencing of
similar temporary objects multiple times. So, lets go back to a sample
application and solve a problem with DPJ.
Figure 5 shows an example where the primary entry point contains numerous
temporary objects in a short portion of Java code, which is using arrays of
different types.
10
Figure 5. DPJ temporary object view.
11
Selecting the first node in the call graph takes the user to a source view (see
Figure 7) that shows the same information being set using a simple array, array
list and linked list. The difference in usage of the temporary objects using
different program techniques is dramatic, and the impact on performance is
noticeable. DPJ helps users, from new to senior, experienced Java engineers,
isolate and solve problems with code efficiency issues.
The user can select the doLinkedList node as in Figure 7 on the call
graph or from the source view to get to the called method that is ultimately
the cause of the heaviest temporary object use. Within the doLinkedList
method, the offending line is found (see Figure 8). In this situation, the Java
compiler optimized the use of linked list arrays by creating and copying
temporary objects many times per line execution and within the loop. You
must either explicitly manage temporary workspace objects for the linked list
array to reduce temporary objects, use a different array type or find another
approach to your object hierarchy besides arrays. Within Java, arrays have
limited benefits for the engineer, but there are reasons to use them. Just be
aware of the impacts and tradeoffs to know how to overcome any drawbacks
as shown in this example.
12
Figure 8. Looking into the linked list array method.
DPJ specifies the number of times the worst-offending line of code was
executed, how many objects it used and how many bytes it used. Getting this
level of information and getting it accurate enough to solve problems is not
viable with manual effort or simple tools like those built into the IDE. DPJ
shows the scope of the problem and helps prioritize your best opportunity for
improvements with temporary object use.
By using DPJs performance profiling capabilities, the user can assess the
performance impact of the specific lines of code using the excessive temporary
objects. An engineer can then make modifications and check the new
performance behaviors. Remaining temporary objects are not a matter of
memory leaks, but a matter of RAM footprint and performance impact.
Engineers cannot completely avoid the use of temporary objects, but they
can make the use of temporary objects more efficient.
13
The net result is that DevPartner Java Edition shifts the focus to fast
Compuware products business solutions and away from time spent on optimizing application code
and professional services and resolving memory or performance bugs.
delivering quality
applications DPJ integrates into JBuilder, WSAD, JDeveloper and OptimalJ as a solution
Compuware is a leading global
to everyday tasks for the developer. DPJs integration into the leading IDEs
provider of software products and
provides immediate access to its features.
professional services which IT
DevPartner Java Edition is also available from the command line and
organizations use to develop,
within an ANT build environment for automation of test results for
integrate, test and manage the
performance, memory and code coverage. The DPJ Server provides
performance of the applications
deployment and server testing for one or multiple tiers. DPJ is the only
that drive their businesses. Our
solution in the market that provides an end-to-end view of all tiers, across all
software products help optimize
machines, all at the same time. You no longer have to shut down the profiling
every step in the application life
tool to reconfigure for a different machine collector. DPJs ability to provide
cyclefrom defining requirements
views of all an applications tiers simultaneously takes the guesswork and extra
to supporting production service
effort out of looking for a needle in a performance haystack; all summary and
levelsfor web, distributed and
detailed information is available for immediate inspection and further analysis.
mainframe platforms. Our services
No other tool can profile and view Java applications the way in which these
professionals work at customer
applications will be deployed: on multiple tiers and multiple machines.
sites around the world, sharing
their real-world perspective and
experience to deliver an
integrated, reliable solution.
Jones, Richard, and Rafael Lins. Garbage Collection: Algorithms for Automatic
Dynamic Memory Management, John Wiley & Sons, New York, 1996.
8/03