Tuesday, July 27, 2021

10 points about Java Heap Space or Java Heap Memory

10 Points about Java heap memory
When I started Java programming I didn't know what is java heap or heap space in Java, I was even not aware of where does object in Java gets created, it’s when I started doing professional programming I came across error java.lang.OutOfMemoryError in Tomcat then I realized What is Heap in Java or Java Heap Space. It happens with most of the programmer because learning language is easy but learning basics are difficult since there is no formal process which can teach you every basic of programming its experience and work which reveals the secret of programming.

For Java developer's knowledge of Heap in Java, setting the size of Java heap space, dealing with Java heap space OutOfMemoryError, analyzing heap dumps is very important. You should read Java Performance from Charlie Hunt to learn more about how to troubleshoot Java performance issues, profiling, and advanced tools to take the heap dump and analyze it to form problem areas.

This Java Heap tutorial is for my beginner brothers who are new in programming and learning it. It makes too much difference if you know the basics and underlying, until you know that object is created in heap, you won't be able to think why OutOfMemoryError occurs in Heap.

I am trying to provide as much information about Heap in Java as I know but would like you guys to contribute and share your knowledge about heap in Java to benefit all.

 By the way, if you are confused between heap and stack, which is where your local variables get created, then, you can also check the difference between heap and stack memory in Java.



What is Heap space in Java?

When a Java program started Java Virtual Machine gets some memory from the Operating System. Java Virtual Machine or JVM uses this memory for all its needs and part of this memory is call java heap memory.

Heap in Java is generally located at bottom of address space and move upwards. whenever we create an object using a new operator or by any other means the object is allocated memory from Heap and When the object dies or garbage collected, memory goes back to Heap space in Java, to learn more about garbage collection see how garbage collection works in Java.

Heap Space in Java


How to increase heap size in Java

The default size of Heap space in Java is 128MB on most of 32 bit Sun's JVM but its highly varies from JVM to JVM e.g. default maximum and start heap size for the 32-bit Solaris Operating System (SPARC Platform Edition) is -Xms=3670K and -Xmx=64M and Default values of heap size parameters on 64-bit systems have been increased up by approximately 30%.

Also, if you are using throughput garbage collector in Java 1.5 default maximum heap size of JVM would be Physical Memory/4 and the default initial heap size would be Physical Memory/16. Another way to find the default heap size of JVM is to start an application with default heap parameters and monitor in using JConsole which is available on JDK 1.5 onwards, on the VMSummary tab you will be able to see maximum heap size.

By the way, you can increase the size of java heap space based on your application need and I always recommend this to avoid using default JVM heap values. if your application is large and lots of objects created you can change the size of heap space by using JVM options -Xms and -Xmx. Xms denotes the starting size of Heap while -Xmx denotes the maximum size of Heap in Java.

There is another parameter called -Xmn which denotes the size of the new generation of Java Heap Space. The only thing is you can not change the size of Heap in Java dynamically, you can only provide Java Heap Size parameter while starting JVM. I have shared some more useful JVM options related to Java Heap space and Garbage collection on my post 10 JVM options Java programmer must know, you may find useful.



Update:

Regarding default heap size in Java, from Java 6 update 18 there are significant changes in how JVM calculates default heap size in 32 and 64-bit machine and on client and server JVM mode:

1) Initial heap space and maximum heap space is larger for improved performance.

2) The default maximum heap space is 1/2 of the physical memory of size up to 192 bytes and 1/4th of physical memory for the size up to 1Gig. So for 1Gig machine maximum heap size is 256MB 2.maximum heap size will not be used until the program creates enough object to fill initial heap space which will be much lesser but at-least 8 MB or 1/64th part of Physical memory up to 1GB.


3) for Server Java virtual machine default maximum heap space is 1G for 4GB of physical memory on a 32 bit JVM. for 64 bit JVM its 32G for physical memory of 128GB.  To learn more about how much memory you can set in 32-bit and 64-bit JVM in the various operating system e.g. Windows 8, Linux, or Solaris, see here.



Java Heap and Garbage Collection

As we know objects are created inside heap memory and Garbage Collection is a process that removes dead objects from Java Heap space and returns memory back to Heap in Java. For the sake of Garbage collection Heap is divided into three main regions named as New Generation, Old or Tenured Generation, and Perm space.

The New Generation of Java Heap is part of Java Heap memory where a newly created object is stored, During the course of the application many objects were created and died but those remain life they got moved to Old or Tenured Generation by Java Garbage collector thread on Major or full garbage collection

Perm space of Java Heap is where JVM stores Metadata about classes and methods, String pool, and Class level details. You can also see the Java and GC online courses for more information on Heap in Java and Garbage collection.





OutOfMemoryError in Java Heap

When JVM starts JVM heap space is equal to the initial size of Heap specified by -Xms parameter, as application progress more objects get created and heap space is expanded to accommodate new objects. JVM also run garbage collector periodically to reclaim memory back from dead objects.

The JVM expands Heap in Java somewhere near to Maximum Heap Size specified by -Xmx and if there is no more memory left for creating new objects in java heap, JVM throws java.lang.OutOfMemoryError and your application die.

Before throwing OutOfMemoryError No Space in Java Heap, JVM tries to run a garbage collector to free any available space but even after that not much space available on Heap in Java it results in OutOfMemoryError.

To resolve this error you need to understand your application object profile i.e. what kind of object you are creating, which objects are taking how much memory etc. you can use a profiler or heap analyzer to troubleshoot OutOfMemoryError in Java.


The "java.lang.OutOfMemoryError: Java heap space" error message denotes that Java heap does not have sufficient space and cannot be expanded further while "java.lang.OutOfMemoryError: PermGen space" error message comes when the permanent generation of Java Heap is full, the application will fail to load a class or to allocate an interned string.


How to increase Java heap space on Maven and ANT

Many times we need to increase the heap size of Maven or ANT because once the number of classes increases build tool requires more memory to process and build and often throw OutOfMemoryError which we can avoid by changing or increase heap memory of JVM. For details see my post How to increase Java heap memory for Ant or Maven



Java Heap dump

Java Heap dump is a snapshot of Java Heap Memory at a particular time. This is very useful to analyze or troubleshoot any memory leak in Java or any java.lang.OutOfMemoryError. There are tools available inside JDK which helps you to take heap dump and there are heap analyzer available tool which helps you to analyze the java heap dump.

You can also use "jmap" command to get a java heap dump, this will create a heap dump file and then you can use "jhat - Java Heap Analysis Tool" to analyze that heap dumps. You should also read Java Performance The Definitive Guide By Scott Oaks to learn more about Java performance tuning and profiling. It is one of the must-read Java performance books for any senior Java developer.

Java Heap space and memory


10 Points about Java Heap Space

1. Java Heap Memory is part of memory allocated to JVM by the Operating System.

2. Whenever we create objects they are created inside Heap in Java.

3. Java Heap space is divided into three regions or generations for sake of garbage collection called New Generation, Old or tenured Generation, or Perm Space. The permanent generation is garbage collected during full gc in hotspot JVM.

4. You can increase or change the size of Java Heap space by using JVM command line option -Xms, -Xmx, and -Xmn. don't forget to add word "M" or "G" after specifying size to indicate Mega or Gig. for example, you can set the java heap size to 258MB by executing following command java -Xmx256m HelloWorld.

5. You can use either JConsole or Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory() to query about Heap size programmatic in Java. See my post How to find memory usage in Java program for more details.

6. You can use command "jmap" to take Heap dump in Java and "jhat" to analyze that heap dump.

7. Java Heap space is different than Stack which is used to store call hierarchy and local variables.

8. Java Garbage collector is responsible for reclaiming memory from a dead objects and returning to Java Heap space.

9. Don’t panic when you get java.lang.OutOfMemoryError, sometimes its just matter of increasing heap size but if it’s recurrent then look for memory leak in Java.

10. Use Profiler and Heap dump Analyzer tool to understand Java Heap space and how much memory is allocated to each object.


68 comments:

  1. @Anand , Thanks for your comment , good to know that you find this post useful. I have already visited your site and found some good information there.

    ReplyDelete
  2. Good post & Nice compilation of all java related blogs. You can also check my blog about technical articles.

    ReplyDelete
  3. What a beautiful and comprehensive explanation...Good work.

    ReplyDelete
  4. @Javin Paul--Thnk you so much for such useful info...:)

    @Anand--Thnk you for providing a info about heap and stack :)

    ReplyDelete
  5. Even though most what you said are correct and help clarify some misunderstanding. But there are some specifics that are not always right. For example,
    "Also if you are using throughput garbage collector in Java 1.5 default maximum heap size of JVM would be Physical Memory/4 and default initial heap size would be Physical Memory/16."
    might only applicable to "server class" machines. I believe it should be 64 instead of 16 for the divider on your statements - based on the SUN's "Tuning Garbage Collection with the 5.0 Java Virtual Machine" section 5.2.2.3 about the default value of DefaultInitialRAMFraction and DefaultMaxRAM. Also, the both values have a cap of 1GB.

    As for "server class", it depends on number of CPU and memory a server has but also depend on the OS and whether it is 32-bit or 64-bit.

    ReplyDelete
  6. Thanks frank for making it more specific. yes you are correct those heap size details are correct when JVM runs on server class. appreciate your input.

    ReplyDelete
  7. Can we increase heap size of java without shutting down our Server. i mean is it possible to change java heap size without JVM closing ?

    ReplyDelete
  8. Hi Anonymous you can not change heap size of JVM once it started in order to increase or decrease heap space in JVM you need to restart it. since some JVM parameter can not modify at run time and java heap size is one of them.

    ReplyDelete
  9. whats is the command to take heap dump in websphere

    ReplyDelete
  10. This is a good article.. very much informative.. one of the statement mentioned in 10 points.. is not appropirate(correct me if i m wrong)

    Runtime.maxMemory() - gives max memory that JVM attempts to claim.
    But you statement says it is the Heap Memory..
    similar with other methods..

    Can you please let me know how one can get the Heap size programmatically..

    ReplyDelete
  11. sir ,,, a question to you that how can you that "Heap in Java generally located at bottom of address space and move upwards".

    ReplyDelete
  12. such a good information on java heap and outofmemoryerror.

    We migrated from BEA WLS 8 to BEA WLS 10 after that we are issues with our application.
    My application is being shoudown frequently due java.lang.OutOfMemoryError but we have no solution how to resolve this issue.

    We have also enhanced the enhanced the java heap size from default values but the servers are being shutdown frequently.

    Any tips would be greatful.

    Thanks
    Fyrose

    ReplyDelete
  13. Hi Fyrose, thanks for your comment, good to know that you find this java heap tutorial useful. I have also blogged about java.lang.OutOfMemoryError and there cause you may find interesting.

    ReplyDelete
  14. Hi,

    I am trying to set a heap space of 2GB using -Xmx2048m, as my program uses huge set of files. I have a 4GB RAM, but still I get an error saying
    "Error occurred during initialization of VM
    Could not reserve enough space for object heap
    Could not create the Java virtual machine."
    I tried stopping/ disabling other services running on my computer, but nothing works. It would be of great help if someone could help me resolve this!

    Thanks in advance!

    ReplyDelete
  15. Hi bblogger, if you are running on 32 bit machine than this is common behavior, theoretically you should be able to set heap size 2GB but practically only around 75% of it is allowed and if heap Size exceeds that number its throws the "Error occurred during initialization of VM"

    ReplyDelete
  16. it helps me a lot...because of u i got some knowledge on heap and stack. why don't you explain us remaining memory areas of JVM like method area, pc registers and netive method area

    ReplyDelete
  17. one stupid question,is perm gen is outside of java heap memory?
    2nd,if i do prstat -a on solaris, i see java process are taking more memory than assigned value by XMX.why does this happen?

    thank you for your article.its clear and precise.

    ReplyDelete
  18. @Anonymous, Perm Gen is part of Java Heap Memory. Java Heap memory is divided into various generations e.g. Eden Space, Survivor space and Perm Space. Perm Space is used to store meta data related to Class and methods required by JVM.

    I think prstat shows total memory consumed by process and not java heap memory. you can think that heap is located inside java process than there is stack area also every thread has own stack etc. So combine memory shown by Operating system should always be greater than Java heap size specified by -Xmx.

    I hope this make sense.

    ReplyDelete
  19. HI i am using Windows server 2008 64-bit and having 12GB of RAM. for my webapplication i am using jre 64 bit as well as Tomcat 7.0.22 64 bit. When i process my data i am getting outofmemory exception. If i install 32bit tomcat then it provides utility to increase heap memory, but in 64 bit i am not able to find. From somewhere i have read that if we create environment variable JAVA_OPTS then it will solve the problem, i have created it but still i am getting the same error please help me to resolve this. Can you tell me the steps to increase the heap memory.

    ReplyDelete
  20. Nice tuto...:-)

    "This Java Heap tutorial is for my beginner brothers who are new in programming and learning it. "

    This impressed me bro....


    Keep going....!

    ReplyDelete
  21. Well what can i say? i saw insufficient heap memory on my phone and the java program went off. so i decided to search what heap means but i realised its not for me but for programmers alone. i don't understand a single sentence in the article.

    ReplyDelete
  22. Hi Unknown, Indeed increasing heap size is programmers job and its a kind of configuration for java program. as a general user you can think heap is a part of memory which a program use to keep its data while it is running and if there is no more space to keep its data it throws outofmemoryerror and went off, I hope that helps.

    ReplyDelete
  23. Great post - very informative!

    A question, and i see you touched base on it a bit above. How does JAVA (JVM) interact with prstat.

    So as an example, i have a java process with XMX @ 2000m. Its current allocated is 800m (of the 2g max). Its current usage is 300m, with 500 free.

    Why would prstat, RSS column, show 1.2g?

    ReplyDelete
  24. Really nice post. In fact all your posts are really insightful and have helped me on numerous occassions. Really appreciate the effort and hope you continue!

    ReplyDelete
  25. Hey Javin - great post. I am a SysAdmin and Java newbie struggling to support a Tomcat app server and this is by far the best article, written in plain English, I have come across about Java memory settings.

    Any chance of an article on Beans - I haven't got a clue what a Bean is - I am sure you could explain in your excellent plain English.

    ReplyDelete
  26. Hi What is maximum heap size for 32 bit JVM and 64 bit JVM, my theory says that it should 2^32 and 2^64 but if you test windows doesn't allow -Xmx even 2GB. please help.

    ReplyDelete
  27. I am facing JVM1 OutOfMemoryException error, I know some class files where leak is happening, can anyone help me by telling some changes to be done, I can nnot increase JVM heap size.
    How about replacing hashMap by WeakHashMap? Can you please give feedbacks or any other better option to solve the issue?

    ReplyDelete
  28. Perm Gen is NOT part of Java Heap Memory.

    ReplyDelete
  29. @Anonymous, unfortunately There is no hard line whether PermGen is on heap or not but practically your are right and yes there space is totally different from space reserved for object allocation. so you can run out of memory even if you have space in heap for object, called Java.lang.outOfMemroy:permGen space.

    ReplyDelete
  30. @Anonymous, are you getting Java.lang.outOfMemroy:permGen space ? that's quite possible because of memory leak I used to face that while working on tomcat check the above link on my experience you may find some help.

    ReplyDelete
  31. @Javin Paul : When we want to learn about Java Heap, we rarely find such good explanation. It's really clear, easy to understand and contains precious information. Thank you

    ReplyDelete
  32. wonderful article ....i was struggling hard to get a concise and specific info regarding java heap and ur article has served the purpose...thanks again...nd keep posting ! Grt job !

    ReplyDelete
  33. A mistake?"for example you can set java heap size to 258MB by executing following command java -Xmx256m ",I think you'd like to say "set java heap size to 256MB",am I right? :-P

    ReplyDelete
  34. @Chorola, Thanks for your comment. isn't it both statements are same e.g. "set java heap size to 256MB"

    ReplyDelete
  35. Hi Javin, again great article on Java Heap there. I'm impressed in your deep dive initiative and sharing.

    OutOfMemoryError can be hard to solve but knowing the foundation of the Java Heap memory is definitely a first step. Once people are familiar with the Java Heap and its different memory spaces, they can then use tools such as Eclipse Memory Analyzer to debug further and understand your Java / Java EE application memory footprint.

    I've used this tool to successfully pinpoint root cause of several memory leaks for my clients Java EE applications and I highly recommend it, plus its completely free.

    Regards,
    P-H

    ReplyDelete
  36. Thanks for your comment P-H. I agree solid knowledge of fundamentals like Java heap space, Thread Stack memory, PermGen space or native C Memory which is used for Memory map file is required to identify exact problem. since every heap space has its boundary and there are different settings to change PermGen space and heap memory.

    ReplyDelete
  37. Was searching to know about Heap size, dint find any article better than this...thanq very much for posting and keep posting...

    ReplyDelete
  38. maximum size of JVM depends upon which operating system you are running, whether JVM is 32 bit or 64 bit etc. on 32 bit JVM maximum size on windows is around 1.5G while in Linux is more than that. default JVM size is again varies from JVM to JVM but I think its 128M or 256M. you can use JVM heap size settings -Xms and -Xmx to change heap size as per your requirement.

    ReplyDelete
  39. Thanks a ton..this is a very good article..

    ReplyDelete
  40. How can I change heap size of JVM for Tomcat in Eclipse ? I am running tomcat inside Eclipse as Server and would like to increase heap size of JVM used in Tomcat

    ReplyDelete
  41. @nikita, You can change heap size of Tomcat JVM by editing catalina.bat on Windows or catalina.sh in Linux. Just provide memory option -Xms and -Xmx to increase heap size as per your need. In case you are concern about PermGen Space in Tomcat look at here

    ReplyDelete
  42. WOOOW A VERY NICE ONE,
    THANKS

    ReplyDelete
  43. Thanks for the info on Heap segment...Very usefull for java beginners like me ...

    ReplyDelete
  44. I am getting following error while running my Java program from command line "could not create the java virtual machine Invalid maximum heap size: -Xmx". The command is java -Xmx 1800M Hello , I have more than 4G of RAM and trying to run this command in Windows XP Machine. Why its saying invalid maximum heap size if I have more tha 4G of memory and creating Java application with 1.8G only ?

    ReplyDelete
  45. I am speaking out of topic, but have to say it...why did you use the phrase "...tutorial is for my beginner brothers". Without being gender biased, you should have used "beginner friends" :)
    Having said that, your blogs are really nice and explainatory. They are very helpful in understanding the concepts that we just know theoritically.

    ReplyDelete
  46. @Anonymous, I agree, Java heap memory is for every one :)

    ReplyDelete
  47. Hello Javin,
    i found your article very useful. i am in very specific problem. i need to load in my java program an image file having size of 18000 * 18000 in pixels so for that i have to use BufferedImage (which creates whole file in a memory at a time) so for that i need (18000 * 18000 * 4 )/ (1024*1024) = 1030 MB of memory approximately , so probably it throws and OutofMemoryException normally. currently i am using 32 bit machine and i have 4 MB of RAM. so if i run this code on 64 bit machine with Xmx 2048 mb would i succeed to load the image without out of memory error ?

    Thank You
    Mihir Parekh

    ReplyDelete
  48. @Mihir, max memory depends upon lot of factor, though theoretical limit for 32 bit JVM is 4GB, you can only allocate around 1.5GB in Windows, more than that, will result in Invalid Maximum Heap Size during JVM startup. On 64 bit machine, I guess 2GB would be find.

    ReplyDelete
  49. This page is a must read for all budding java developers to build some basics.

    ReplyDelete
  50. This author adequately demonstrates how JAVA and .NET programmers know not how computers work. They are not even properly educated on memory management, I/O, or data management. When I learned C you had to manage your STACK and HEAP. You had to KNOW what these mean and how they affected your program. Now I meet "professional" programmers who have NO CLUE how computers, networks, or data actually work. All they know is that they type this code and magic fairies make things happen. And, their code is usually awful, fat, and slow.

    ReplyDelete
  51. Javin, you are doing wonderful job dude. I feel lucky to go through your pages. They are so friendly, so straight forward, so interactive with very good narration and you make it really simple to learn. Identification of topics is so well done that i feel every blog page is a must read page. Thanks and wish you have huge fan base. Thanks again.

    ReplyDelete
  52. @Akshay, Welcome to Javarevisited, and thanks for kind words.

    ReplyDelete
  53. The point "2. Whenever we create objects they are created inside Heap in Java." it's not actually always true. The JVM has a feature called escape analysis which in some circumstances allocate the object on stack rather than heap.

    ReplyDelete
  54. one mistake is, heap doesnot need to start from bottom of address space (actually is virtual memory).
    another one is, not all garbage collections need to be generational garbage collection, such as mark-sweep garbage collection, it really differs from each other in real application.
    one more not all objects need to be in heap, as someone already points out.

    ReplyDelete
  55. I got these kind of errors .. what is this whether heap size is full or permsize is unable to load.

    org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet SafeTestServlet threw exception
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    Exception in thread "Timer-0" java.lang.OutOfMemoryError: GC overhead limit exceeded
    Feb 14, 2014 10:17:32 AM msjava.kerberos.auth.MSKerberosAuthenticator authenticate
    INFO: User = palc; Status = Authenticated
    Exception in thread "schedulerfactorybean_QuartzSchedulerThread" java.lang.OutOfMemoryError: GC overhead limit exceeded
    Feb 14, 2014 10:20:07 AM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet SafeTestServlet threw exception
    java.lang.OutOfMemoryError: GC overhead limit exceeded

    ReplyDelete
  56. Hi, I have cross-compiled the IcedTea JDK for Linux device. Is there any way that I can freeze the max java heap size for all java apps? I mean user can't change the heap size, every java app will have the same max heap space?

    ReplyDelete
  57. Please let me know difference between servlet memory and heap memory

    ReplyDelete
  58. @Unknown, never heard about servlet memory, can you please clarify where did you heard that, what is the context behind it?

    ReplyDelete
  59. Hi, Very nice article.

    I have used Xms= 4G and Xmx=8G in my Java application. I was expecting that on start application it will consume atleast of 4GB (as Xms is set to 4GB) from OS. But it is not the case it used only about a GB and then gradually increase over days to 4 and then continue till 8GB. I am running this application on windows 2008 R2.

    Any Idea why JVM does not take allocated -Xms value straight away on start of Application ?

    ReplyDelete
  60. What is the difference between Java heapspace and tomcat heap space?

    ReplyDelete
  61. @Javin... truly you are a good blogger. Whenever I read your article I always learn something new. Thanks for this wonderful work.
    Keep serving java community.. 😃

    ReplyDelete
  62. Fantastic info used for my long time doubts about JVM

    ReplyDelete
  63. I have an issue with an applet build. Can anyone tell me how to specify more space to get around this error:
    ---------------------
    When building a smart card applet I get:

    Error: class java.lang.ArrayIndexOutOfBoundsException, Array index out of range: 25305
    java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 25305
    at com.ibm.jc.apps.tric.c.g$d.a(Unknown Source)
    at com.ibm.jc.apps.tric.jc.JCClazz$a.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.c.i.a(Unknown Source)
    at com.ibm.jc.apps.tric.jc.JCCab.O(Unknown Source)
    at com.ibm.jc.apps.tric.jc.Converter.a(Unknown Source)
    at com.ibm.jc.apps.tric.jc.CapConverter.createImage(Unknown Source)

    If I comment out one or more arrays, all is well.

    I seem to be running into an applet size restriction during the build process. Does anyone have any ideas how I can get around this?

    Thanks.

    ReplyDelete
  64. you can declare the array size when you are creating the array, it seems you don't know the exact number of element before hand. In that, just use ArrayList instead of Array and initialize ArrayList with 25000.

    ReplyDelete
  65. Thank you for explaining this!

    ReplyDelete
  66. My pleasure, glad you find it useful.

    ReplyDelete