You are on page 1of 13

JVM Runtime Data Areas

The Java virtual machine defines various runtime data areas that are used during execution of a program. Some of these data areas are created on Java virtual machine start-up and are destroyed only when the Java virtual machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits
Stack

Stack is a memory place where the methods and the local variables are stored. ariable references !either primitive or ob"ect references# are stored in the Stack . $ach thread has a private stack% which stores frames. The following exceptional conditions are associated with Java virtual machine stacks &f the computation in a thread re'uires a larger Java virtual machine stack than is permitted% the Java virtual machine throws a StackOverflow$rror. &f Java virtual machine stacks can be dynamically expanded% and expansion is attempted but insufficient memory can be made available to effect the expansion% or if insufficient memory can be made available to create the initial Java virtual machine stack for a new thread% the Java virtual machine throws an OutOf(emory$rror Heap )eap is a memory place where the ob"ects and its instance variable are stored. $ach time an ob"ect is created in Java it goes into the area of memory known as heap. Information about HEAP The heap is created on virtual machine start-up. )eap storage for ob"ects is reclaimed by an automatic storage management system !known as a garbage collector#* ob"ects are never explicitly deallocated. The heap may be of a fixed si+e or may be expanded as re'uired by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous. , Java virtual machine implementation may provide the programmer or the user control over the initial si+e of the heap% as well as% if the heap can be dynamically expanded or contracted% control over the maximum and minimum heap si+e. The following exceptional condition is associated with the heap &f a computation re'uires more heap than can be made available by the automatic storage management system% the Java virtual machine throws an OutOf(emory$rror

)eap and stack are the two main memories that J ( is concerned as far as memory allocation by the OS !operating system# is concerned. Stack and heap are the memories allocated by the OS to the J ( that runs in the system.

JVM Internals & Runtime Data Areas.doc

Page 1

The primitive variables like int and double are allocated in the stack% if they are local method variables and in the heap if they are member variables !i.e. fields of a class#. &n Java methods local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed. &n a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is .threadsafe/ !each thread will have its own stack# but the heap is not .threadsafe/ unless guarded with synchroni+ation through your code. Method Area &t is shared among all threads. &t stores per-class structures such as the runtime constant pool% field and method code. &t is logically part of the heap. (emory for class !static# variables and methods declared in the class is also taken from it. Runtime Constant Pool r Constant Pool &t is a per-class or per-interface runtime representation of the constant0pool table. The J ( maintains a per-type constant pool% including literals !string% integer% and floating point constants#. $ach runtime constant pool is allocated from the J ( method area. !rame or Stack !rame 1rame holds local variables !including parameters#% operand stack and partial results% and plays a part in method invocation and return. , new frame is created each time a method is invoked and is destroyed on method completion. $ach frame has a reference to the runtime constant pool of the class of the current method. PC Re"ister The Java virtual machine can support many threads of execution at once. $ach Java virtual machine thread has its own pc !program counter# register. ,t any point% each Java virtual machine thread is executing the code of a single method% the current method for that thread. &f that method is not native% the pc register contains the address of the Java virtual machine instruction currently being executed. &f the method currently being executed by the thread is native% the value of the Java virtual machine2s pc register is undefined. The Java virtual machine2s pc register is wide enough to hold a return,ddress or a native pointer on the specific platform. An E#ample $ class (emory 3 static int x* public static void main!String67 args#3 (emory memory 8 new (emory!#* int y 89*

45 static stack storage54 45 dynamic heap storage54

String myString = new String(Memory);


: :

/* dynamic stack storage */ /* dynamic heap storage */

;hen you create an ob"ect using the new operator% for example memory = new (emory();% it allocates memory for the memory ob"ect on the heap. The stack memory space is used when you declare automatic variables. <ote% when you do a string initiali+ation% for example String myString;% it is a reference to an ob"ect so it will be created using new and hence it will be placed on the heap.

JVM Internals & Runtime Data Areas.doc

Page 2

(emory space for ob%ects is always allocated in heap. Ob"ects are placed on the heap. &uilt'in datat(pes like int% double% float and parameters to methods are allocated on the stack.

JVM Performance )unin"


The application server% being a Java process% re'uires a Java virtual machine !J (# to run% and to support the Java applications running on it. ,s part of configuring an application server% you can fine-tune settings that enhance system use of the J (

Heap Si*e
The allocation of memory for the J ( is specified using -= options Options -=ms -=mx -=mn (eaning initial "ava heap si+e maximum "ava heap si+e the si+e of the heap for the young generation

&t is good practice with server-side Java applications like >esin to set the minimum -=ms and maximum -=mx heap si+es to the same value. 1or efficient garbage collection% the -=mn value should be lower than the -=mx value. )eap si+e does not determine the amount of memory your process uses. &f you monitor your "ava process with an OS tool like top or taskmanager% you may see the amount of memory you use exceed the amount you have specified for -=mx. -=mx limits the "ava heap si+e% "ava will allocate memory for other things% including a stack for each thread. &t is not unusual for the total memory consumption of the ( to exceed the value of -=mx.

Stack Si*e
$ach thread in the ( get2s a stack. The stack si+e will limit the number of threads that you can have% too big of a stack si+e and you will run out of memory as each thread is allocated more memory than it needs. Options -=ss (eaning the stack si+e for each thread

-=ss determines the si+e of the stack- -Xss1024k. &f the stack space is too small% eventually you will see an exception "ava.lang.StackOverflow$rror.

JVM Internals & Runtime Data Areas.doc

Page 3

Internal architecture of the Ja+a +irtual machine

JVM Internals & Runtime Data Areas.doc

Page

Runtime Data Areas

3ati4e Method Stack "#$%&' 1 PC STACK -er method &rea 1rame 1rame (perand Stack )oca* +aria,*es $e2erence s -artia* $es.*ts

J (
#%&/*ass instances and &rrays 0nstance +aria,*e -er c*ass ,asis Method Area
$.ntime /onstant -oo* Method /ode Static +aria,*es

Shared among a** threads "#$%&' 2 PC STACK -er method &rea 1rame 1rame

)oca* +aria,*es (perand Stack -artia* $es.*ts

Dealin" ,ith Memor( -eaks


.hat is it/
(emory leaks occur when a program never stops using an ob"ect% thus keeping a permanent reference to it. 1or $xample ? class (emory@eak 3 private static @istABoubleC memory@eak@ist 8 new ,rray@istABoubleC!#* public static void main!String67 args#3 double d 8 9.9* 44 infinite loop would eventually run out of memory while!true#3 Bouble dbl 8 new Bouble!d#* memory@eak@ist.add!dbl#* dDD* : : : &f you run this program% ;hen no more memory is remaining% an OutOf(emory$rror alert will be thrown and generate an exception like this -

JVM Internals & Runtime Data Areas.doc

Page !

$xception in thread EmainF "ava.lang.OutOf(emory$rror- Java heap space at (emory@eak.main!(emory@eak."ava-G# &n the example above% we continue adding new elements to the list memory@eak,rea without ever removing them. &n addition% we keep references to the memory@eak,rea% thereby preventing HI from collecting the list itself. So although there is HI available% it cannot help because we are still using memory. The more time passes the more memory we use% which in effect re'uires an infinite amount memory for this program to continue running. This is an example of unbounded memory leakJthe longer the program runs% the more memory it takes. So even if the memory si+e is increased% the application will still run out of memory at a later date.

Determinin" if an application has a memor( leak


To understand what is going on% we need to familiari+e ourselves with how the J ( uses system memory for its heap. ;hen running "ava.exe% you can use certain options to control the startup and maximum si+e of the garbage-collected heap !-ms and -mx% respectively#. The Sun JBK L.L.M uses a default L (N startup setting and a LO (N maximum setting. The &N( JBK L.L.M uses a default maximum setting of one-half the total physical memory si+e of the machine. These memory settings have a direct impact on what the J ( does when it runs out of memory. The J ( may continue growing the heap rather than wait for a garbage collection cycle to complete. So for the purposes of finding and eventually eliminating a memory leak% we are going to need better tools than task monitoring utility programs. (emory debugging programs can come in handy when you2re trying to detect memory leaks. These programs typically give you information about the number of ob"ects in the heap% the number of instances of each ob"ect% and the memory being using by the ob"ects. &n addition% they may also provide useful views showing each ob"ect2s references and referrers so that you can track down the source of a memory leak. )his e#ample I ha+e taken from http011%a+a2d*one2com <ot every OutOf(emory$rror alert indicates that a program is suffering from a memory leak. Some programs simply need more memory to run. &n other words% some OutOf(emory$rror alerts are caused by the load% not by the passage of time% and as a result they indicate the need for more memory in a program rather than a memory leak. To distinguish between a memory leak and an application that simply needs more memory% we need to look at the Epeak loadF concept. ;hen program has "ust started no users have yet used it% and as a result it typically needs much less memory then when thousands of users are interacting with it. Thus% measuring memory usage immediately after a program starts is not the best way to gauge how much memory it needsP To measure how much memory an application needs% memory si+e measurements should be taken at the time of peak loadJwhen it is most heavily used.

JVM Internals & Runtime Data Areas.doc

Page 5

The graph below shows the memory usage in a healthy Java application that does not suffer from memory leaks% with the peak load occurring around L9 ,( and application usage drastically decreasing at Q P(. <aturally% the peak load on business applications often correlates with normal business hours.

The application illustrated by the chart above reaches its peak load around L9 ,( and needs around R99(N of memory to run. This is normal behavior for an application suffering from no memory leaks* the difference in memory re'uirements throughout the day is caused solely by the user load. <ow% let/s suppose that we have a memory leak in the application. The primary characteristic of memory leaks is that memory re'uirements increase as a function of time% not as a function of the load. @et/s see how the application would look after running for a few days with a memory leak and the same peak user loads reached around L9 ,( every day-

JVM Internals & Runtime Data Areas.doc

Page 6

Necause peak loads on the system are similar every morning but memory usage is growing over a period of a few days% this picture indicates a strong possibility of memory leaks. &f the program eventually started suffering from OutOf(emory exceptions% it would be a very strong indication that there/s a problem with memory leaks. The picture above shows a memory leak of about L99(N per day. <ote that the key to this example is that the only thing changing is the amount of time the system is upJthe system peak load doesn/t change over time. This is not the case for all businesses. 1or example% the peak load for a tax preparation service is seasonal% as there are likely more users on the system in ,pril than July. There is one special case that should be noted here- a program that needs to be restarted periodically in order to prevent it from crashing with an OutOf(emory$rror alert. &magine that on the previous graph the max memory si+e was LL99(N. &f the program started with about R99(N of memory used% it would take about SM hours to crash because it leaks about L99(N of memory per day. Similarly% if the max memory si+e was set to L999(N% the program would crash every TS hours. )owever% if the program was regularly restarted more often than this interval% it would appear that all is fine. >egularly scheduled restarts may appear to help% but also might make Eupward sloping memory useF !as shown in the previous graph# more difficult to notice because the graph is cut short before the pattern emerges. &n a case like this% you/ll need to look more carefully at the memory usage% or try to increase the available memory so that it/s easier to see the pattern.

JVM Internals & Runtime Data Areas.doc

Page 7

Monitorin" Memor( in Ja+a


There are a couple of options for measuring the amount of memory a program uses. The simplest one% which does not re'uire any tools and works even with production systems% is the erbose HI log. Verbose 3C -o" The erbose HI log is defined when the J ( process is started. There are a couple of switches that can be usedL. -verbose-gc J prints basic information about HI to the standard output T. -==-DPrintHITimeStamps J prints the times that HI executes U. -==-DPrintHIBetails J prints statistics about different regions of memory in the J ( S. -=loggc-AfileC J logs the results of HI in the given file The following is an example of the output generated for Tomcat running in the default configuration with all of the previous switches enabledL.MQS- 6HI L.MQS- 6Bef<ew- QG9K-COTK!QGOK#% 9.99LTUQQ secs7 TOTUK-CTLGQK!URM9K#% 9.99LTRTT secs7 L.MGL- 6HI L.MGL- 6Bef<ew- QGSK-CQQK!QGOK#% 9.999RML9 secs7 TOMGK-CTTTRK!URM9K#% 9.99L9GQT secs7 L.MML- 6HI L.MML- 6Bef<ew- QOGK-CU9K!QGOK#% 9.999GSLG secs7 TGSLK-CTTQGK!URM9K#% 9.999GRSG secs7 L.MR9- 6HI L.MR9- 6Bef<ew- QSTK-COSK!QGOK#% 9.99LTLQQ secs7 TGORK-CTTRQK!URM9K#% 9.99LTM9M secs7

The most important set of numbers is located in the second column after the second -C !e.g.% in the top line shown it is TOTUK-CTLGQK!URM9K#. These numbers indicate that as a result of HI% we are using around TT99K of memory at the end of each HI cycle. This trace is not an indication of a memory leakJit shows a short-term trend with less then a second between samples% and that/s why we must observe long-term trends. )owever% if the erbose HI log showed that the program was using around TT99K of memory after running for two days% and after running for L9 days it was using THN of memory !even after HI had "ust run#% we could then conclude that there/s a memory leak. ,ll the information that needs to be collected in order to determine if a memory leak exists can be found in the results of the erbose HI logs. Monitorin" the Ja+a Process The following approach works for any Java process% including standalone clients as well as application servers like JNoss and servlet containers like Tomcat. &t is based on starting the Java process with J(= monitoring enabled and attaching with the J(= monitoring tools. ;e/ll use Tomcat in the following example. To start Tomcat or the Java process with J(= monitoring enabled% use the following options when starting J (-

JVM Internals & Runtime Data Areas.doc

Page 8

-Bcom.sun.management."mxremote J enables J(= monitoring -Bcom.sun.management."mxremote.port8AportC J controls the port for J(= monitoring

<ote that if you/re on a production system% you/ll most likely want to secure your J ( before running it with these parameters. 1or that% you can specify these additional options com.sun.management."mxremote.ssl com.sun.management."mxremote.authenticate isual ( to attach to the process. <ote that later

Once started% you can use JIonsole or JBK O versions include isual (.

Heap Dump
, heap dump is a list of ob"ects in the memory of J ( as well as the content of the memory occupied by those ob"ects. &t preserves the value of any attributes of the ob"ects% including references to other ob"ects. &n other words% a heap dump gives you a complete picture of the memory. There are multiple tools that allow you to dump heap in a Java process-

&f you/re using JBK O% you can use tool called "map on any platform. &f you/re using JBK Q% the situation is slightly more complex&f you/re running V<&= !@inux% Solaris% OS =# with JBK Q you can use "map. &f you/re using JBK Q update LS or later% you can use the -==D)eapBumpOnItrlNreak option when starting J (% then use the IT>@DN>$,K key combination on ;indows !or IT>@ D W on V<&=# to dump the heap. &f you/re running ;indows and using JBK Q pre-update LS% you/ll soon wish you weren/t. Trying to reproduce the problem with a more recent JBK is probably the best bet here.

Some tools like isual ( and memory profilers allow you to initiate a heap dump from the HV&% but you don/t need any fancy tools hereJ"map will do "ust fine. ,s it provides the most general case% we/ll use "map in the next example. Nefore you dump heap% be sure to keep the following issues in mind Programs in the J ( should be paused for the duration of the heap dump% which might take anywhere from ten seconds to several minutes. (any enterprise applicationsJand users of those applicationsJdon/t take kindly to pauses that long% which may cause various timeouts to expire. So don/t try this at home or in production !unless the application is already a goner#P

JVM Internals & Runtime Data Areas.doc

Page 19

)eap dumps are saved on disk% and the files might be fairly large. , good rule is to make sure that you have at least twice the si+e of the physical memory free on the disk before you initiate a memory dump.

;ith those final words of caution out of the way% you should now be ready to run the following command"map -heap-live%format8b%file81&@$<,($ P&B <ote that the -1 option% which will dump non-responsive programs% might be useful on V<&= systems% but is not available on ;indows. <ote also that JBK O includes the option D==D)eapBumpOnOutOf(emory$rror that will dump heap whenever the OutOf(emory$rror alert is encountered. This can be a useful option% but keep in mind that it has the potential to consume significant amounts of disk space. Xou now have a heap dump in the file 1&@$<,($ and are ready to analy+e it.

.hat4s In 5-eaked6 Memor(/


;ith the heap dump complete% we can now take a look at the memory and find out what/s really causing the memory leak. Suppose that ob"ects are holding references to each other as illustrated by the picture below. 1or the sake of easy calculation% let/s assume that each ob"ect is L99 bytes% so that all of them together occupy O99 bytes of memory.

<ow% suppose that the program holds reference to ob"ect , for a prolonged period of time. ,s a result% ob"ects N% I% B% $% and 1 are all ineligible for garbage collection% and we have the following amount of memory leaking L99 bytes for ob"ect , Q99 bytes for ob"ects N% I% B% $ and 1 that are retained due to the retention of ob"ect ,

JVM Internals & Runtime Data Areas.doc

Page 11

So% holding reference to ob"ect , causes a memory leak of O99 bytes. The shallow heap of ob"ect , is L99 bytes !ob"ect , itself#% and the retained heap of ob"ect , is O99 bytes. ,lthough ob"ects , through 1 are all leaked% the real cause of the memory leak is the program holding reference to ob"ect ,. So how can we fix the root cause of this leakY &f we first identify that ob"ect 1 is leaked% we can follow the reference chain back through ob"ects B% I and , to find the cause of the memory leak. )owever% there are some complications to this Efollow the reference chainF process >eference chains can be really long% so manually following them can be time consuming ,n ob"ect is sometimes retained by more than one ob"ect% and there can even be circles involved as shown in the picture below-

&f we start following inbound references from ob"ect 1 in this example% we have to choose between following ob"ect I or ob"ect B. &n addition% there/s the possibility of getting caught in a circle by repeatedly following the path between ob"ects B% $ and N. On this small diagram it/s easy to see that the root cause is holding ob"ect ,% but when you/re dealing with a situation that involves hundreds of thousands of ob"ects !as any self-respecting memory leak does# you 'uickly reali+e that manually following the reference chain be very complex and time consuming. This is where some shortcuts can come in handy-

&f we had a tool that allowed us to play a Ewhat would happen if & remove this referenceF type of guessing game% we could run experiments that help locate the cause. 1or example% we could see that if we removed reference from EIause of @eakF to , in the diagram above% ob"ects , through 1 would all be freed. Some tools !like Zuest/s JProbe# have this capability. &f the memory leak is large and we have a tool that allows us to sort ob"ects by retained heap% we/ll get an even greater head start because the ob"ects with the largest retained heap are usually the cause of large memory leaks.

JVM Internals & Runtime Data Areas.doc

Page 12

<ow that we understand what memory leaks are and how they can be corrected% let/s find out how to fix them by analy+ing heap dumps.

)ools for Dealin" ,ith Heap Dumps


Tools often provide a few extra helpful features ? Present a better summary of heap statistics. Sort ob"ects by retained heap. &n other words% some tools can tell you the memory usage of an ob"ect and all other ob"ects that are referenced by it% as well as list the ob"ects referenced by other ob"ects. This makes it much faster to diagnose the cause of a memory leak. 1unction on machines that have less memory then the si+e of the heap dump. 1or example% they/ll allow you to analy+e a LOHN heap dump from your server on a machine with only LHN of physical memory.

VisualVM is nice tool that gives you "ust enough to resolve memory leaks% and it shows heap dumps and relations between ob"ects in graphical form. 1eature-wise% one step above isual ( is the $clipse (emory ,naly+er Tool !(,T#% a free tool that includes a lot of additional options. ,lthough it/s still in incubation phase as of publication of this article% (,T is free and we/ve found it to be extremely useful. Iommercial products like JProfiler% 7our8it% and JProbe are also excellent tools for debugging memory leaks. These applications include a few options that go above and beyond isual ( and (,T% but they/re certainly not necessary to successfully debug memory leaks.

JVM Internals & Runtime Data Areas.doc

Page 13

You might also like