Application Performance : Part II
Posted by sureshkrishna on October 28, 2007
I have been dealing with many of the java applications for years and in the recent past i am finding all the areas that effect the performance. I have been reading lot of books and articles and i thought that a summary would help everyone. In the past 2 months, i have been reading the book Java Performance Platform. Thanks to the authors, they have really given valuable information in this book. As always, “Its not enough to read this book but to consciously write applications that takes care of the memory management and performance”.
Many of the developers and IT does complain about the huge foot print by applications and some times its difficult to know whats causes the foot print. Applications becomes memory hogs and instead of looking into the root cause, we tweak JVM settings, increase the virtual memory, increase the PermGen size, custom class loading. I am sure and any of you would agree that we do “all sorts of things” for the application performance. I have written some notes on the Garbage Collection (which is Application Performance – Part I) in my previous blog. The current “notes” concentrates on the causes for the RAM footprint and different aspects of the things that we need to be aware of.
Memory foot print of the program is tricky to find out. Many of developers do look into the TaskManager to see RAM usage by the application. This definitely gives an idea of how much of memory your application requires. When this memory increases over a period of time, we suspect memory leaks and take corrective actions.
Programmatic Memory Usage : Certain in formation can be derived from the java.lang.Runtime class. This class can look for the heap size of the JVM. Two methods namely Runtime.totalMemory() and Runtime.freeMemory() gives the size (in bytes) information that many of us want. Heap memory can only give the size of the objects. But the actual size of the application is a combination of the Objects, Classes, Threads, Native Data Structures, Native Code.
App Runtime Size = funtion of (Objects + Classes + Threads + Native Data Structures + Native Code)
Depending on the OS, JVM and application the actual memory consumption changes. So any one of the above parameters could be the number one memory consumer for a particular application. In general the memory consumption depends on following items (but not limited to).
- usage the native code
- usage of java core libraries
- bulk of the frameworks used in the application
- number of classes loaded against the objects used
Most of the developers do have a great deal of control over the Objects and their sizes. It could help if the developer knows the approximate size contributed by the objects at the run-time to see what is the optimization area. i.e. if object memory is only a small % of the total size then perhaps we could concentrate on the classes or native libraries, etc.
When classes are loaded into the memory, there are few more dependant entities that contribute to the RAM footprint. Bytecodes is the intermediate format that a java class file gets compiled to. It is necessary that the bytecode gets loaded into the RAM. All the related contents are parsed and reflective data structures are created for methods and fields. Constant pool is defined for all the classes. e.g. all the String literals are present in this constant pool along with all the class, method and fields names. Threads are another important item that could cause a large memory foot print. Its necessary to see what kind of computation is done in the Thread and what data-structures are used. Many of the UI level libraries/frameworks like SWT, AWT does depend on some sort of the native libraries. Its difficult to know which class of these frameworks directly access the native libraries.
Knowing some of the entities that increases the memory footprint would help many of developers. If not completely avoid the large memory footprints, we can at least be aware and work towards conscious usage of resources.