Java Memory Sizing procedure (Pragmatic approach)
Download excel file http://scn.sap.com/servlet/JiveServlet/download/38-182521/MemoryCalculation_v1.0.xlsx.txt.zip to calculate java memory for an application!
Read the blog to understand the calculations!
SAP delivers multiple java-based products, running on top of SAP Netweaver Java platform using SAP JVM [see 1].
Often the required java memory is calculated by applying some ratio, for example 4 GB memory per 1000 SAPS [see 2] or is determined in experimental way for a concrete usage, or even it is not calculated at all but later, in production, changes to JVM parameters are applied as reaction to already experienced java memory problems.
This blog suggests a pragmatic approach to calculate the required memory for java applications based on defined application memory consumption metrics (KPI [see 3]). It calculates the amount of physical memory which should be available on the hardware and recommends best-fit configuration (JVM settings and number of Java server nodes) of the SAP Java Server cluster.
Be aware that Java Memory Sizing is only relevant to applications, which do not introduce logical memory leaks[see 4] – the java memory sizing prevents only from memory shortage situations, which are not leaks.
 KPI = Key Performance Indicators
 Memory leak examples in following articles: http://www.ibm.com/developerworks/library/j-leaks/ and http://www.javaworld.com/javaworld/javaqa/1999-08/04-qa-leaks.html
Short overview on JVM Memory Management
It is typical for Java applications that
– most of the created objects become unused very soon
– many objects and classes, once instantiated, remain in memory for a long time
To serve to this reality, Java Virtual Machine implements a concept of separate memory areas for different ages and types of objects/classes: young generation, tenured generation and permanent generation.
The Java Virtual Machine (JVM) manages objects de-allocation automatically using varies garbage collection algorithms. Nowadays are invented and implemented many intelligent garbage collection algorithms with multiple configuration parameters, which optimize the frequency of occurrence and minimize the duration of garbage collection.
The garbage collection duration depends on the garbage collection algorithm, the size of the young, tenured and permanent generation area, the CPU processing speed, some specific influencing factors like implementation of finalize() method of java objects, and so on. With bigger heaps or with less powerful CPUs, the duration of both small and major garbage collection is longer. Memory paging increases the duration of the garbage collection to unacceptably long execution times, and thus it is absolutely essential to have the complete java heap inside the main memory of the machine.
ℹ Example for duration of small garbage collection
On CPU @ 2.66GHz , -Xms=4096M –Xmx=4096M –XX:PermSize=512M –XX:MaxPermSize=512M –XX:NewSize=820M –XX:MaxNewSize=820M, the minor (small) garbage collection takes about 0.8-0.9 seconds.
ℹ Example for duration of full garbage collection:
On CPU @ 2.66GHz, -Xms=4096M –Xmx=4096M –XX:PermSize=512M –XX:MaxPermSize=512M –XX:NewSize=820M –XX:MaxNewSize=820M, the major (full) garbage collection takes about 9-10 seconds.
With the major (full) garbage collection the entire heap must be examined for unnecessary objects, that is why it is much slower compared to small garbage collection.
➕ SAP recommends to use the JVM parameters -XX:+UseConcMarkSweepGC and -XX:+UseParNewGC to enable parallel garbage collection algorithms.
➕ SAP recommends that the values for JVM parameters pairs -Xms and –Xmx, –XX:PermSize and –XX:MaxPermSize, –XX:NewSize and –XX:MaxNewSize should be set to same value – in this way heap areas will not resize at runtime, because the resize is associated with worst performance.
Usually customers choose heap sizes (-Xms and –Xmx) between 2 GB and 8 GB per Java Server node. Larger heaps are not very common, though possible.
The young generation consists of one eden space and two survivor spaces. Objects are initially created in the eden space. One survivor space is empty at any time, and serves as a destination of any live objects that are not collected by the minor (small) garbage collection from the eden space and the other survivor space. Objects are copied between survivor spaces until they are old enough to be copied to the tenured generation. When the survivor space is too small to hold the surviving objects, the overflowing objects are copied directly into the tenured generation.
If in tenured generation is left less free space than the total size of the eden space and one survivor, major (full) garbage collection is started. The situation is known as “young generation guarantee”. For this reason the tenured generation size depends on the size of the young generation size and practically should be significantly bigger than the young generation space.
The permanent generation holds data of classes and methods. Typically its content is stable over time and shortage of space in the permanent generation is rarely occurring, unless programming patterns with runtime class/methods generation are used by the application. When the permanent generation space needs to be cleaned, a major (full) garbage collection is triggered.
Native code area
The JVM implementation needs space outside defined heap, let’s name it “Native code area”. Consider at maximum 1 GB per JVM for it.
Short overview on basic memory consumption metrics (KPI)
in SAP Java Application Server environment
SAP defined memory metrics (KPI) to determine the memory consumption profile of applications running on top of NetWeaver Java Application Server. In the article “Best Practices for Java Performance & Load Tests”[see 5] are presented three memory KPIs (slide 11, 12, 13 and 14) – Framework Space, Session Space and Processing Space with description of corresponding measurement procedure and two garbage collection KPIs (slides 16 and 17) – GC duration and GC interval.
Framework Space [MB]
The so called Framework Space is filled with objects created during initialization of java server services, libraries, applications, etc. and objects of shared caches, pools, etc. Such objects typically live for the entire life time of the java virtual machine and therefore are always promoted to the tenured generation. The corresponding to those objects classes and methods, defined as Perm Framework Space, stay in permanent generation for the complete live-time of java server.
ℹ The measurement for Framework Space and Perm Framework Space is done via analysis of heap dumps, taken after warm-up (execution with different test users of the main functional scenarios) of the sized application. It is important that at the time when the heap dump is taken the users are no longer active on the server node – they should be either logged out or their sessions should have expired.
Use Memory Analyzer tool.
User Session Space [MB per session]
The so called Session Space is filled with objects related to the user session and temporary caches which are removed if the user leaves the system due to log out, or timeout. A user is connected to the system for at least several minutes – the Session Space objects usually live long enough to be promoted to tenured generation and from tenured generation area they could be removed only with major (full) garbage collection.
ℹ The memory measurement for user Session Space and user Perm Session Space is usually done with analysis of a heap dump, taken while multiple users are logged in to the system and are executing different dialog steps of the important functional scenarios of the sized application.
Use Memory Analyzer tool.
Processing Space [MB per dialog step]
The Processing Space is filled with short living objects which typically are ready to be immediately garbage collected directly in the young generation space after replying to a user request [see 6] is completed.
ℹ The memory measurement for Processing Space is based on the total size of all object allocations done in the thread, or multiple threads, which are executing the user request. The Processing Space includes not only the objects which are temporary allocated and garbage collected for processing the user request but also those objects which will become part of caches or session space, i.e. will be promoted to tenured generation after small garbage collection.
Use SAP JVM Profiler tool.
 User request can be a http request to Java server from browser, but as well any other remote or local call executed by Java server received and answered on any of the communication protocols, which are supported. For the purpose of this paper, it could be also any periodic task, which is activated and executed on the server, even if no external communication is involved.
Goal of Java Memory Sizing
The goal of java memory sizing is to minimize the frequency and duration of garbage collection, i.e. to determine with which (application specific) size of
– young generation, a minimum amount of objects would be copied into the tenured generation
– tenured generation, a minimum number of full garbage collections would be executed
– permanent generation, a minimum number of full garbage collections would be executed
If best conditions for minimum duration of GC are in place via selection of the best optimized garbage collection algorithm, fast CPU model and adequate sizes of generation areas, we can effectively define “target” garbage collection intervals to ensure that garbage collection does not happen too frequently.
The frequency, defined as interval between two successive garbage collection (GC) occurrences, is a required input parameter for memory sizing.
Let‘s define Isgc and Ifgc
· Isgc = interval of small garbage collection (in seconds), for example 3 seconds
It is recommended that Isgc is longer compared to average response time for particular end user request. For example, if the average response time per request is 1-2 seconds then target interval of 3 seconds is good enough. If the average response time is 3 seconds, then it is better to select target interval for small garbage collection about 4-5 seconds. The intention is to make sure that between two small garbage collections some end user requests are completed and thus more memory could be recycled. If many requests are still “in process” then with small garbage collection memory cannot be recycled (still in use) and might be promoted to the tenured generation.
· Ifgc = interval of full garbage collection (in seconds), for example 1020 seconds (17 minutes)
The Ifgc interval should depend on the average duration of end user session. If user session on average is 15 minutes long then a target full garbage collection interval of 16-17 minutes will be ok. If the user session is about 30 minutes long, the target full gc interval should be adjusted to higher value. When full garbage collection is running, but user sessions are still active and the session memory cannot be recycled, the system performance is usually bad with a real danger of crash with “Out of Memory” (OOM) error.
Formulas for Java Memory Sizing
The total amount of memory which is required to hold all user sessions is calculated like
(F1) Total Sessions Space [MB] = Number of concurrent users*UserSessionSpace [MB] + Number of new sessions per second*UserSessionSpace [MB] * Ifgc
❗ The user session could have different size after execution of different dialog steps of the scenarios. For “pessimistic” sizing take the maximum measured session size (peak session size) among all user sessions and for “normal” sizing take the average user session size.
❗ Not only the currently active sessions are included in the sizing but also the new sessions which will be created between two sequential collections are considered and planned for session space.
If tenured generation is sized only for the currently alive sessions, then every new created user session may trigger full garbage collection. This full garbage collection will not able to collect enough unused Sessions Space memory, because most of the user sessions are still alive and very soon a new full garbage collection will be required and the frequency of full garbage collections will increase. To avoid this effect in the tenured generation there must be planned capacity to handle new incoming sessions which replace the logged out or expired sessions without need that those unused objects are immediately garbage collected.
In some application implementations, classes and methods are created at runtime (so called “runtime class/method generation”). In such cases the size of permanent generation area will depend on the number of concurrent users too – the delta growth per user session will be application specific and determined as additional memory KPI: PermUserSessionSpace [MB/user].
(F1a) Total Permanent Sessions Space [MB] =
Number of concurrent users*PermUserSessionSpace[MB] + Number of new sessions per second*PermUserSessionSpace[MB] * Ifgc
There is relation between the number of user sessions and the requests per second, which are processed:
Requests per second = (Number of concurrent users) / (Average response time [s] + Think time [s])
Given this, it is easy to calculate the total processing space required by java objects, generated between two sequential small garbage collections in “Isgc interval”
(F2) Total Processing Space [MB] = Requests per second * Processing space [MB] * Isgc
❗ With SAP Java Server there is no mechanism to split the total required Framework Space or Perm Framework Space into parts and put it to different JVMs. Therefore the required Framework Space or Perm Framework Space is allocated within the tenured generation and within the permanent generation, of every Java Virtual Machine, i.e. on every Java sever node.
This means that with every Java Server node the tenured generation and permanent generation sizes should always be bigger than framework spaces, i.e.
Tenured generation[MB] > Framework Space[MB]
Permanent generation[MB] > Perm Framework Space[MB]
Determine physical memory requirements and Java Server configuration
After Framework Space [MB] (also Perm Framework Space [MB]) is measured, and Sessions Space [MB] (also Perm Sessions Space [MB]) and Processing Space [MB] are calculated using formulas F1, F1a and F2, to complete memory sizing remains to
Determine the cluster configuration – heap size and number of java server nodes
Heap size [MB] = Framework Space[MB] + (2 * Total Processing Space [MB] + Total Sessions Space [MB]) / (Number of Server nodes)
Perm size [MB] = Perm Framework Space[MB] + (Total Permanent Sessions Space [MB]) / (Number of Server nodes)
Multiple combinations of Number of Server nodes and Heap (Perm) sizes are possible.
ℹ If more server nodes with smaller heap are preferred, then the total physical memory requirement would be higher due to the fact that each server would have own native code area for initialization of the JVM and that the framework space memory is repeated in each and every server node.
➕ For stability and failover reasons choose java cluster configuration with at least 2-3 java server nodes.
ℹ If less server nodes with bigger heap are preferred, then longer duration of the garbage collection is expected.
➖ Avoid too many server nodes, e.g. more than 10, because of possible increased startup times in cluster.
Calculate the total amount of required physical memory
Physical memory [MB] = Number of Server nodes * (Heap size [MB] + Perm size [MB] + Native code area [MB])
What to deliver as sizing?
In java memory sizing guideline it is not necessary to provide all details of measured memory, neither formulas for calculation.
As result of all sizing calculations, the sizing guideline can look like a table where the sizing expert has decided on the optimal number of server nodes and appropriate heap sizes, for example:
|Category||Up to …
– all java servers
of server nodes
heap size [GB]
per server node
|more||contact SAP||contact SAP||contact SAP||contact SAP|
The java memory sizing is application-specific. If more than one application is intensively used in given java environment, the java memory sizing should be calculated for the total usage.
❗ Java Applications, which set in advance memory KPIs for session space (e.g. up to 5 MB per session) and processing space (e.g. up to 10 MB per request) and manage to fulfill it during development will have low memory requirements and good performance.