Understanding Java memory

This article takes a simplistic approach for individuals to understand about memory allocated to Java. I'm a true believer that new learning should be built on prior knowledge of which allows an individual to deepen their existing understanding instead of starting from scratch. I'm assuming you know something about java though unless you're highly intuitive, understanding java memory performance issues can become difficult to grasp and easily forgotten. I've deliberately avoided any technical jargon for the initial phase to prevent individuals stopping mid-sentence to look up the terminology though by the end of this blog hope you understand java in it's correct form.
July 18, 2012
Java

Java is a greedy fat kid

A nieve approach to Java would be that it's considered greedy when it comes to memory. You allocate and dedicate the memory instead of sharing it. This allocation of memory is stored within something called a java heap (Like a big bucket to hold memory). The memory you've allocated together with other hardware + software components from the OS constructs something called a Java virtual Machine (JVM). (As the name states, a JVM a virtual machine that can be located your computer or server)

Of course this is by design. With the constant demand of memory allows the JVM to execute applications without the worry of other applications sucking the computer resources. You can configure how much memory to allocate by using the values -Xms (the initial allocation of memory) and -Xmx (the maximum amount it can store in it's java heap). As java is an object orientated program, it creates objects. These objects require memory. Java will allocate memory to the objects from the JVM heap (or in other words, the java heap from the JVM).


The Garbage Collectors

Question is, what happens to the memory that it's been allocated? Well, the object still retains the memory and continues to do so even if the object is now idling or referenced by other objects. So what happens when new objects need that memory that the idle object was initially allocated? This is where the Garbage Collection comes into play. When around 80% of the memory has been allocated, the garbage collector will start and release any memory allocated to idling objects and place this back into the java heap.

It's a nice approach on managing objects though what happens if the memory cannot be released by simple garbage collection? The solution here is to do a full garbage collection by suspending the JVM and cleaning up everything. This is by design and may not cause a problem if JVM has not been allocated enough memory. The full garbage collector will occur more frequently and continue to suspend the JVM prolonging it's required tasks.

Applying the JVM too much memory is also a problem because even though it's happy doing it's thing, it will eventually get to that 80% threshold and will then require a simple garbage collection though this time round a simple cleanup will be much longer comb-through when releasing memory . Eventually the garbage collector will execute a full cleanup thus leaving the JVM suspended for much longer.

So the challenge here is to determine how much memory is needed to start -Xms without applying too much memory -Xmx.


Java Memory Leaks

Another terminology that is often used out of context is Java Memory Leaks. Referring back to the garbage collection topic, imagine a poorly-designed java code which creates new objects within a never ending loop. If this is the case, it will create an infinite amount of object and continue to hand out memory for each of these objects. If the object is still in use, the garbage collector cannot assist by releasing the memory which will eventually leave the JVM without any available memory and eventually eventually come to a complete halt.

There's a well constructed java article on how to fix memory leaks in java. At the moment this isn't by biggest concern as I'm measuring java memory and not memory leaks though I would recommend you having a quick read.


java.lang.OutOfMemoryError: PermGen space

Imagine an application server which needed to load a very large number of classes just for the startup phase. It would be illogical to allocate it a huge amount of memory to the heap size for just 1 effort. Instead, the JVM will retrieve this additional memory from outside the heap and from the OS - this is called the PermGen Size thus allowing the JVM to execute large 1-time efforts. This issue will occur if the OS is unable to provide any free memory to the JVM.

The thumb in the air rule is that you should have the PermSize a quarter the size of the MaxHeapSize.


java.lang.OutOfMemoryError: Java Heap space

Just like the paragraph above, the OutOfMemoryError is now a java heap size issue, not a PermSize. Even though it's out of memory error, there considered to be separate issues. In the previous example, the OS does not have any free memory, in this case the JVM has simply not been allocated enough memory within the heap size.

The solution here would be to increase the -Xmx. It's also recommended that if the Xmx increases so must the PermSize (recommended relation is 1:4)

Understanding the differential between these issues is a big step into learning java though this link from Oracle dives more into Java memory error notifications + explanations.


Conclusion

  • Java will require it's own memory to execute applications.
  • Java retrieves this from the OS into it's own java heap and will run programs within the Java virtual Machine (JVM).
  • The common Java parameters to use for performance as as follows:
    • Xms = Initial Java Heap size allocation
    • Xmx = Maximun Java Heap size allocation
    • -XX:PermSize = Normal PermSize (additional memory taken from the OS)
    • -XX:MaxPermSize = Max PermSize allowed
  • The recommended MaxPermSize should be MaxHeapSize/4. So if the MaxHeapSize is 2GB, the MaxPermSize should be .5GB.

About the author

Daniel is a Technical Manager with over 10 years of consulting expertise in the Identity and Access Management space.
Daniel has built from scratch this blog as well as technicalconfessions.com
Follow Daniel on twitter @nervouswiggles

Comments

Other Posts

AWS-PHP integration - Email not sent. SMTP Error: Could not authenticate.

phpsmtpaws

February 6, 2020
Created by: Daniel Redfern
AS I was migrating my environment into an S3 environment, I wanted to leverage off the SES services that AWS provide, more specifically, to leverage the off the SMTP functionality by sending an email via PHP
Read More...

SOLUTION: no headers files (.h) found in softwareserial - Arduino

Arduino

February 24, 2019
Created by: Daniel Redfern
The WeMos D1 is a ESP8266 WiFi based board is an extension to the current out-of-the-box library that comes with the Arduino installation. Because of this, you need to import in the libraries as well as acknowledging the specific board. This process is highly confusion with a number of different individuals talking about a number of different ways to integrate.
Read More...

NameID element must be present as part of the Subject in the Response message

ShibbolethSAML

August 7, 2018
Created by: Daniel Redfern
NameID element must be present as part of the Subject in the Response message, please enable it in the IDP configuration.
Read More...

HOW TO provision AD group membership from OpenIDM

OpenIDMICFAD-connector

June 15, 2018
Created by: Daniel Redfern
For what I see, there's not too many supportive documentations out there that will demonstrate how provision AD group membership with the ICF connector using OpenIDM. The use of the special ldapGroups attribute is not explained anywhere in the Integrators guides to to the date of this blog. This quick blog identifies the tasks required to provision AD group membership from OpenIDM to AD using the LDAP ICF connector. However this doesn't really explain what ldapGroups actually does and there's no real worked example of how to go from an Assignment to ldapGroups to an assigned group in AD. I wrote up a wiki article for my own reference: AD group memberships automatically to users This is just my view, others may disagree, but I think the implementation experience could be improved with some more documentation and a more detailed example here.
Read More...

ForgeRock OpenIDM - InvalidCredentialException: Remote framework key is invalid

ICFIDMOpenIDMOpenICF

November 8, 2017
Created by: Daniel Redfern
In the past, the similar error occurred though for the Oracle Identity Management solution. invalidcredentialexception remote framework key is invalid Because they all share the ICF connector framework, the error/solution would be the same.
Read More...

org.forgerock.script.exception.ScriptCompilationException: missing ; before statement

IDMsync.confforgerockopenidm

November 8, 2017
Created by: Daniel Redfern
org.forgerock.script.exception.ScriptCompilationException: missing ; before statement
Read More...

ForgeRock IDM - org.forgerock.script.exception.ScriptCompilationException: missing ; before statemen

OpenIDMsync.confForgeRock

September 17, 2017
Created by: Daniel Redfern
ForgeRock IDM - org.forgerock.script.exception.ScriptCompilationException: missing ; before statement
Read More...

Caused by: org.forgerock.json.resource.BadRequestException: Target does not support attribute groups

OpenIDMForgeRockICFConnector

September 17, 2017
Created by: Daniel Redfern
When performing the attempt of a reconciliation from ForgeRock IDM to Active Directory, I would get the following error
Read More...

ForgeRock OpenIDM - InvalidCredentialException: Remote framework key is invalid

OpenIDMForgeRockICFConnectorAD

September 17, 2017
Created by: Daniel Redfern
In the past, the similar error occurred though for the Oracle Identity Management solution. invalidcredentialexception remote framework key is invalid Because they all share the ICF connector framework, the error/solution would be the same.
Read More...

ERROR Caused by com.google.api.client.auth.oauth2.TokenResponseException 400 Bad Request - invalid_g

OpenIDMIDMGoogleGoogle-AppsICFreconciliation

September 12, 2017
Created by: Daniel Redfern
During the reconcilation from OpenIDM to the ICF google apps connector, the following error response would occur. ERROR Caused by com.google.api.client.auth.oauth2.TokenResponseException 400 Bad Request - invalid_grant
Read More...