By Jack Shirazi
Book Price: $44.95 USD
£31.95 GBP
PDF Price: $35.99
Cover | Table of Contents | Colophon
System.currentTimeMillis(
)
and then
subtract this from a later timestamp to determine the elapsed time.
This works well for elapsed time measurements that are
not short. Other types of
measurements have to be
system-specific and
often application-specific. You can measure:main( ) to maintest(
), and call maintest( ) twice from a new
main( )).http://www.JavaPerformanceTuning.com/resources.shtml.
These tools are usually available free for an evaluation period, and
you can quickly tell which you prefer using. If your budget covers
it, it is worth getting several profilers: they often have
complementary features and provide different details about the
running code. I have included a list of profilers in Chapter 19.System.currentTimeMillis(
)
in the code to get timestamps is the only
reliable way to determine the time taken by each part of the
application. In addition, System.currentTimeMillis(
) is quick and has no effect on application timing (as long
as you are not measuring too many intervals or ridiculously short
intervals; see the discussion in Section 1.7).-verbosegc
option with the VM. This option prints
out time and space values for objects reclaimed and space recycled as
the reclamations occur. The 1.4 VM introduced an additional option to
log the output to a file instead of standard error: the
-Xloggc:<file>
option. Printing directly to a file is
slightly more efficient than redirecting the VM output to a file
because the direct file write buffering is slightly more efficient
than the piped redirect buffering. The printout includes explicit
synchronous calls to the garbage collector (using System.gc(
)
) as well as asynchronous executions of
the garbage collector, as occurs in normal operation when free memory
available to the VM gets low.System.gc( ) does not necessarily force a
synchronous garbage collection. Instead, the gc( )
call is really a hint to the runtime that now is a good time to run
the garbage collector. The runtime decides whether to execute the
garbage collection at that time and what type of garbage collection
to run. In more recent VMs, the effects of calling
System.gc( ) can be completely disabled using the
runtime flag XX:+DisableExplicitGC.-verbosegc. The following code
fragment creates lots of objects to force the garbage collector to
work, and also includes some synchronous calls to the garbage
collector:package tuning.gc;
public class Test {
public static void main(String[ ] args)
{
int SIZE = 4000;
StringBuffer s;
java.util.Vector v;
//Create some objects so that the garbage collector
//has something to do
for (int i = 0; i < SIZE; i++)
{
s = new StringBuffer(50);
v = new java.util.Vector(30);
s.append(i).append(i+1).append(i+2).append(i+3);
}
s = null;
v = null;
System.out.println("Starting explicit garbage collection");
long time = System.currentTimeMillis( );
System.gc( );
System.out.println("Garbage collection took " +
(System.currentTimeMillis( )-time) + " millis");
int[ ] arr = new int[SIZE*10];
//null the variable so that the array can be garbage collected
time = System.currentTimeMillis( );
arr = null;
System.out.println("Starting explicit garbage collection");
System.gc( );
System.out.println("Garbage collection took " +
(System.currentTimeMillis( )-time) + " millis");
}
}foo( ) at the top of the stack, then the
assumption is that method foo( ) takes 10% of the
running time. However, this is a sampling
technique
, so it is not
foolproof: methods can be missed altogether or have their weighting
misrecorded if some of their execution calls are missed. But usually
only the shortest tests are skewed. Any reasonably long test (i.e.,
seconds rather than milliseconds) normally gives correct results.java executable with the
-Xrunhprof
option (% java -Xrunhprof:format=b <classname>
java.lang.Object class to catch most nonarray
object-creation calls. This is not a supported feature, but it does
seem to work on most systems because all constructors chain up to the
Object class's
constructor, and any explicitly created
nonarray object calls the constructor in Object as
its first execution point after the VM allocates the object on the
heap. Objects that are created implicitly with a call to
clone( ) or by deserialization do not call the
Object class's constructor, and
so are missed when using this technique.Object class with this
book. But I can show you the simple changes to make to the
java.lang.Object class to track object creation.Object
constructor to pass this to some object-creation
monitor you are using. java.lang.Object does not
have an explicitly defined constructor (it uses the default empty
constructor), so you need to add one to the source and recompile. For
any class other than Object, that is all you need
to do. But there is an added problem in that
Object does not have a superclass, and the
compiler has a problem with this: the
compiler cannot handle an explicit freeMemory(
)
and totalMemory( ) in
the java.lang.Runtime class.totalMemory( ) returns a long,
which is the number of bytes currently allocated to the runtime
system for this particular VM process. Within this memory allocation,
the VM manages its objects and data. Some of this allocated memory is
held in reserve for creating new objects. When the currently
allocated memory gets filled and the garbage collector cannot
allocate sufficiently more memory, the VM requests more memory from
the underlying system. If the underlying system cannot allocate any
further memory, an
OutOfMemoryError
error is thrown. Total memory can go up
and down; some Java runtimes return sections of unused memory to the
underlying system while still running.freeMemory( ) returns a long,
which is the number of bytes available to the VM to create objects
from the section of memory it controls (i.e., memory already
allocated to the runtime by the underlying system). The free memory
increases when a garbage collection successfully reclaims space used
by dead objects, and also increases when the Java runtime requests
more memory from the underlying operating system. The free memory
reduces each time an object is created and when the runtime returns
memory to the underlying system.Runtime.maxMemory(
)
.
This method simply gives the -Xmx value, and is of
no use to monitor heap usage.freeMemory( ) and
totalMemory( )System.currentTimeMillis( ) to get timestamps
if you need to determine absolute times. Never use the timings
obtained from a profiler as absolute times.Runtime.totalMemory( ) and
Runtime.freeMemory( ) methods to monitor gross
memory usage.-verbosegc option. This prints out
time and space values for objects reclaimed and space recycled. The
printout includes explicit synchronous calls to the garbage collector
(using -verbosegc option. This prints out
time and space values for objects reclaimed and space recycled. The
printout includes explicit synchronous calls to the garbage collector
(using System.gc( )) as well as asynchronous
executions of the garbage collector, as occurs in normal operation
when free memory available to the VM gets low. You can try to force
the VM to execute only synchronous garbage collections by using the
-noasyncgc option to the Java executable (no
longer available from JDK 1.2). The -noasyncgc
option does not actually stop the garbage-collector thread from
executing; it still executes if the VM runs out of free memory (as
opposed to just getting low on memory). Output from the garbage
collector running with -verbosegc is detailed in
Section 2.2.-Xmx/-mx option). The garbage
collector's space-reclamation algorithm tends to
change with each version of the JDK.-mx/-Xmx and
-ms/-Xms. Respectively, these
parameters set the maximum and
starting sizes of the heap in bytes.
They are typically available with every VM.-mx and
-ms parameters or the -Xmx and
-Xms parameters, or both. They also vary about
accepting a space between the number following the parameter and
accepting shorthand notations of K and M for kilobytes and megabytes,
e.g., -Xmx32M. Check the documentation or simply
try the various possibilities for your VM).-XX:NewSize, refer to the
combination Young+Scratch. The -Xmx parameter
sizes Old+New. The full heap is Old+New+Perm.-XX:MinFreeHeapRatio=
num,
where num is 0 to 100, to specify that the
heap should be expanded if less than num%
of the heap is free. Similarly, the
-XXMaxHeapFreeRatio parameter specifies when the
heap should be contracted. The IBM VM uses -Xminf
and -Xmaxf with decimal parameters between 0 and 1
(e.g., 20% is 20 for the Sun VM and 0.2 for the IBM VM). The Sun
default is to try to keep the proportion of free space to living
objects at each garbage collection within the 40%-70% range. That is,
if less than 40% of the heap is free after a garbage collection (so
more than 60% of the heap is full of objects), then the heap is
expanded. Otherwise, the next garbage collection will likely occur
sooner than desired. (IBM defaults are 0.3 min and 0.6 max.)http://www.javagroup.org/echidna/) that takes
care of all the subtleties involved in running multiple applications
independently within the same VM system process. The library also
provides several management tools to help use Echidna effectively. If
you want to know how Echidna works or need to use parts of the
library within your project, I have written an article that covers
the technology in some detail.