Java Performence


How would you improve performance of a Java application? PI BP

 Pool valuable system resources like threads, database connections, socket connections etc. Emphasise on reuse of threads from a pool of threads. Creating new threads and discarding them after use can adversely affect performance. Also consider using multi-threading in your single-threaded applications where possible to enhance performance. Optimze the pool sizes based on system and application specifications and
requirements.
Optimize your I/O operations: use buffering (Refer Q21 in Java section) when writing to and reading from
files and/or streams. Avoid writers/readers if you are dealing with only ASCII characters. You can use streams
instead, which are faster. Avoid premature flushing of buffers. Also make use of the performance and
scalability enhancing features such as non-blocking and asynchronous I/O, mapping of file to memory etc
offered by the NIO (New I/O).
Minimize network overheads by retrieving several related items simultaneously in one remote invocation if possible. Remote method invocations involve a network round-trip, marshalling and unmarshalling of parameters, which can cause huge performance problems if the remote interface is poorly designed. (Refer Q125 in Enterprise section).


Establish whether you have a potential memory problem and manage your objects efficiently: remove references to the short-lived objects from long-lived objects like Java collections etc (Refer Q64 in Java
section) to minimise any potential memory leaks. Also reuse objects where possible. It is cheaper to recycle
objects than creating new objects each time. Avoid creating extra objects unnecessarily. For example use mutable StringBuffer/StringBuilder classes instead of immutable String objects in computation expensive loops as discussed in Q17 in Java section. Automatic garbage collection is one of the most highly touted conveniences of Java. However, it comes at a price. Creating and destroying objects occupies a significant
chunk of the JVM's time. Wherever possible, you should look for ways to minimise the number of objects created in your code:
 If repeating code within a loop, avoid creating new objects for each iteration. Create objects before
entering the loop (i.e. outside the loop) and reuse them if possible.
 For complex objects that are used frequently, consider creating a pool of recyclable objects rather than
always instantiating new objects. This adds additional burden on the programmer to manage the pool,
but in select cases can represent an order of magnitude performance gain.
Use lazy initialization when you want to distribute the load of creating large amounts of objects. Use lazy
initialization only when there is merit in the design.
Where applicable apply the following performance tips in your code:
Use ArrayLists, HashMap etc as opposed to Vector, Hashtable etc where possible. This is because the
methods in ArrayList, HashMap etc are not synchronized (Refer Q13 in Java Section). Even better is to
use just arrays where possible.
Set the initial capacity of a collection (e.g. ArrayList, HashMap etc) and StringBuffer/StringBuilder
appropriately. This is because these classes must grow periodically to accommodate new elements.
So, if you have a very large ArrayList or a StringBuffer, and you know the size in advance then you can
speed things up by setting the initial size appropriately. (Refer Q15, Q17 in Java Section).
Minimise the use of casting or runtime type checking like instanceof in frequently executed methods
or in loops. The “casting” and “instanceof” checks for a class marked as final will be faster. Using
“instanceof” construct is not only ugly but also unmaintainable. Look at using visitor pattern (Refer Q11 in How would you go about…? section) to avoid “instanceof” construct.


 Do not compute constants inside a large loop. Compute them outside the loop. For applets compute it
in the init() method.
Exception creation can be expensive because it has to create the full stack trace. The stack trace is
obviously useful if you are planning to log or display the exception to the user. But if you are using your
exception to just control the flow, which is not recommended, then throw an exception, which is precreated.
An efficient way to do this is to declare a public static final Exception in your exception class
itself.
Avoid using System.out.println and use logging frameworks like Log4J etc, which uses I/O buffers (Refer Q21 in Java section).
Minimise calls to Date, Calendar, etc related classes.
Minimise JNI calls in your code.
Note: Set performance requirements in the specifications, include a performance focus in the analysis and design
and also create a performance test environment.
Q 64: How would you detect and minimise memory leaks in Java? MI BP
A 64: In Java memory leaks are caused by poor program design where object references are long lived and the garbage
collector is unable to reclaim those objects.
Detecting memory leaks:
 Use tools like JProbe, OptimizeIt etc to detect memory leaks.
Use operating system process monitors like task manager on NT systems, ps, vmstat, iostat, netstat etc on UNIX systems.
 Write your own utility class with the help of totalMemory() and freeMemory() methods in the Java Runtime
class. Place these calls in your code strategically for pre and post memory recording where you suspect to be
causing memory leaks. An even better approach than a utility class is using dynamic proxies (Refer Q11 in
How would you go about section…) or Aspect Oriented Programming (AOP) for pre and post memory
recording where you have the control of activating memory measurement only when needed. (Refer Q3 – Q5
in Emerging Technologies/Frameworks section).
Minimising memory leaks:
In Java, typically memory leak occurs when an object of a longer lifecycle has a reference to objects of a short life cycle.
This prevents the objects with short life cycle being garbage collected. The developer must remember to remove the references
to the short-lived objects from the long-lived objects. Objects with the same life cycle do not cause any issues because the
garbage collector is smart enough to deal with the circular references (Refer Q33 in Java section).
Design applications with an object’s life cycle in mind, instead of relying on the clever features of the JVM.
Letting go of the object’s reference in one’s own class as soon as possible can mitigate memory problems.
Example: myRef = null;
Unreachable collection objects can magnify a memory leak problem. In Java it is easy to let go of an entire collection by setting the root of the collection to null. The garbage collector will reclaim all the objects (unless some objects are needed elsewhere).
Use weak references (Refer Q32 in Java section) if you are the only one using it. The WeakHashMap is a combination of HashMap and WeakReference. This class can be used for programming problems where you need to have a HashMap of information, but you would like that information to be garbage collected if you are the only one referencing it.

Free native system resources like AWT frame, files, JNI etc when finished with them. Example: Frame, Dialog, and Graphics classes require that the method dispose() be called on them when they are no longer used, to free up the system resources they reserve.