Tuesday, June 19, 2012
One of the major benefits of the Java language in comparison with other object oriented languages (like C++) is that programmers do not have to handle memory allocation during execution of the program. It is totally delegated to the garbage collector (GC) which is in charge of removing unused objects to release memory.
JVM memory organisation
- the heap memory
- the non heap memory
The heap memory
The heap is devided into two generations: The Young Generation and the Tenured Generation.
Non optimal performance
Excessive footprintReference http://batterywalam.wordpress.com/category/j2ee-diagnostics/jvm-tuning/jvm-memory-organization
Monday, June 18, 2012
Came across this wonderful explanation by Mike regarding XA transactions here
An XA transaction, in the most general terms, is a "global transaction" that may span multiple resources. A non-XA transaction always involves just one resource. An XA transaction involves a coordinating transaction manager, with one or more databases (or other resources, like JMS) all involved in a single global transaction. Non-XA transactions have no transaction coordinator, and a single resource is doing all its transaction work itself (this is sometimes called local transactions).
XA transactions come from the X/Open group specification on distributed, global transactions. JTA includes the X/Open XA spec, in modified form. Most stuff in the world is non-XA - a Servlet or EJB or plain old JDBC in a Java application talking to a single database. XA gets involved when you want to work with multiple resources - 2 or more databases, a database and a JMS connection, all of those plus maybe a JCA resource - all in a single transaction. In this scenario, you'll have an app server like Websphere or Weblogic or JBoss acting as the Transaction Manager, and your various resources (Oracle, Sybase, IBM MQ JMS, SAP, whatever) acting as transaction resources. Your code can then update/delete/publish/whatever across the many resources. When you say "commit", the results are commited across all of the resources. When you say "rollback", _everything_ is rolled back across all resources.
The Transaction Manager coordinates all of this through a protocol called Two Phase Commit (2PC). This protocol also has to be supported by the individual resources. In terms of datasources, an XA datasource is a data source that can participate in an XA global transaction. A non-XA datasource generally can't participate in a global transaction (sort of - some people implement what's called a "last participant" optimization that can let you do this for exactly one non-XA item).
Tuesday, June 12, 2012
If you're used to using a language such as C and are not used to dealing with Unicode, you may expect a string to essentially take up one byte per character plus a single byte terminator. But in a language such as Java, gone are those days:
- every object has at least 8 bytes of housekeeping data, and arrays 12 bytes, and will be padded to a multiple of 16 bytes (in 32-bit versions of Hotspot);
- a Java String actually consists of more than one object;
- a Java char takes up two bytes, even if you're using them to store boring old ASCII values that would fit into a single byte;
- a Java String contains some extra variables that you might not have considered.
How to calculate String memory usage
For reasons we'll explore below, the minimum memory usage of a Java String is generally as follows:
Minimum String memory usage (bytes) = 8 * (int) ((((no chars) * 2) + 38) / 8)
Or put another way:
Or put another way:
- multiply the number of characters of the String by two;
- add 38;
- if the result is not a multiple of 8, round up to the next multiple of 8;
- the result is generally the minimum number of bytes taken up on the heap by the String.
Understanding String memory usage
To understand the above calculation, we need to start by looking at the fields on a String object. A String contains the following:
- a char array— thus a separate object— containing the actual characters;
- an integer offset into the array at which the string starts;
- the length of the string;
- another int for the cached calculation of the hash code.
This means even if the string contains no characters, it will require 4 bytes for the char array reference, plus 3*4=12 bytes for the three int fields, plus 8 bytes of object header. This gives 24 bytes (which is a multiple of 8 so no "padding" bytes are needed so far). Then, the (empty) char array will require a further 12 bytes (arrays have an extra 4 bytes to store their length), plus in this case 4 bytes of padding to bring the memory used by the char array object up to a multiple of 16. So in total, an empty string uses 40 bytes.
If the string contains, say, 17 characters, then the String object itself still requires 24 bytes. But now the char array requires 12 bytes of header plus 17*2=34 bytes for the seventeen chars. Since 12+34=46 isn't a multiple of 8, we also need to round up to the next multiple of 8 (48). So overall, our 17-character String will use up 48+24 = 72 bytes. As you can see, that's quite a long way off the 18 bytes that you might have expected if you were used to C programming in the "good old days"1.
General formula for calculating memory usage
In general, the heap memory used by a Java object in Hotspot consists of:
- an object header, consisting of a few bytes of "housekeeping" information;
- memory for primitive fields, according to their size ;
- memory for reference fields (4 bytes each);
- padding: potentially a few "wasted" unused bytes after the object data, to make every object start at an address that is a convenient multiple of bytes and reduce the number of bits required to represent a pointer to an object.
Java type Bytes required boolean 1 byte char 2 short int 4 float long 8 double
- a normal object requires 8 bytes of "housekeeping" space;
- arrays require 12 bytes (the same as a normal object, plus 4 bytes for the array length).
Object size granularity
In Hotspot, every object occupies a number of bytes that is a multiple of 8. If the number of bytes required by an object for its header and fields is not a multiple 8, then you round up to the next multiple of 8.
This means, for example, that:
- a bare Object takes up 8 bytes;
- an instance of a class with a single boolean field takes up 16 bytes: 8 bytes of header, 1 byte for the boolean and 7 bytes of "padding" to make the size up to a multiple of 8;
- an instance with eight boolean fields will also take up 16 bytes: 8 for the header, 8 for the booleans; since this is already a multiple of 8, no padding is needed;
- an object with a two long fields, three int fields and a boolean will take up:
- 8 bytes for the header;
- 16 bytes for the 2 longs (8 each);
- 12 bytes for the 3 ints (4 each);
- 1 byte for the boolean;
- a further 3 bytes of padding, to round the total up from 37 to 40, a multiple of 8.