Performance and price are two big considerations in application hosting that always matter. And, very often, we question ourselves on how to decrease dollars spent, without affecting the performance of apps at the same time. In this article we’d like to address automatic memory management for Java applications hosted with Jelastic using Garbage Collection.
Firstly, let’s define what Garbage Collection is and what it does for your Java app. And then we will be more specific about Garbage Collection processes in Jelastic’s Cloud.
Java Garbage Collection Overview
Garbage Collection (GC) is a form of automatic memory management. Its aim is to find data objects in memory that are no longer demanded and make their space available for reuse.
The created object uses some memory that remains allocated until there are references for the use of the object. When there are no references for an object, it is considered to be no longer required and the memory occupied by the object can be reclaimed. In such a way, you don’t pay for unused resources and can cut your costs.
Jelastic Default GC Settings
In one of our earlier publications we covered the topic of Garbage Collection (GC) in Jelastic. There, we tested different kinds of Garbage Collectors and defined the most appropriate for the Java applications hosted on our cloud, taking into consideration the automatic vertical scaling that we provide.
Since then, we continued to experiment to find the best solution. As a result of our new investigations, we changed the default settings of Garbage Collectors in Jelastic in order to increase the benefits for our users.
Now, if no custom GC is specified, Jelastic will configure it as follows:
- ParNew for all servers with resource limits below 8GB
- G1 for servers with resource limits above 8GB (64 cloudlets and more)
In this case, it doesn’t matter how many cloudlets are actively consumed. Garbage Collector takes into consideration a Scaling Limit – the maximum amount of cloudlets that you set for each server.
ParNew Garbage Collector
ParNew is a “stop-the-world” multi-threaded Garbage Collector. It collects the young generation of objects. Since the young generation is normally small in size, in Jelastic this ParNew collector is used only for servers with resource limits below 8GB. Based on the size, the collection is very fast and does not impact your application too much. In addition, ParNew collector has a compaction of unused RAM that enables support of automatic vertical scaling – one of the prominent Jelastic features.
Garbage-First Garbage Collector
The Garbage-First (G1) collector is a server-style Garbage Collector for multi-processor machines with large memories. The heap is partitioned into fixed-sized regions and G1 tracks the live data in those regions. When Garbage Collection is required, it collects from the regions with less live data first.
G1 is focused on applications that require large heaps with limited GC latency. After deep analysis, we reached the conclusion that 8GB of RAM consumption is big enough for using G1.
Together with these settings, a special Jelastic GC agent is used to release unused RAM by JVM to OS (more details are described below in this article).
Customization of GC Settings in Jelastic Cloud
If you believe that the default Jelastic settings of garbage collector can have a negative impact on your application, you can tune them according to the requirements of your app. We recommend to customize these configurations only if you fully understand the impact of such changes on your app’s performance.
You can set a custom GC parameter based on your application requirements by:
- editing the variables.conf file of your Tomcat, TomEE or Jetty server
- editing JVM option in the admin panel of GlassFish server
1. To configure Tomcat, TomEE or Jetty open Conf files of your Java server.
2. Navigate to the server > variables.conf file.
3. In the opened variables.conf file you can configure garbage collector settings by stating the needed parameter in the following format:
4. While configuring GlassFish, you need to use the same format of GC parameter.
Open GlassFish admin panel, navigate to Configurations > gfcluster-config > JVM Settings > JVM Options and edit the appropriate JVM Option as it is shown in the picture below.
5. After this, only the specified garbage collector will be used while starting your Java server without taking into consideration the amount of allocated resources.
Note that Jelastic GC agent works only with two kinds of Garbage Collector:
So, if you specify another GC manually, then calling full GC will be disabled.
6. Also, you can reduce the usage of CPU power by GC and control how JVM handles its heap memory. For that you need to tune the frequency of GC processes by stating -Xmx and -Xms switches.
-Xmx switch is used to start the JVM with a higher maximum heap memory and to release CPU time for the important processes.
-Xms parameter is stated to ensure that the size of JVM’s initial heap memory is equal to the maximum allocated memory (Scaling Limit).
These parameters should be specified in the variables.conf file for Tomcat,TomEE and Jetty or in JVM Options for GlassFish.
-Xmx< size >m
-Xms< size >m
Jelastic Garbage Collection Agent
Currently JVM does not have any feature to call full GC periodically. Releasing reserved, but at the same time unused RAM by JVM to OS is required for automatic vertical scaling, configured in Jelastic Cloud. That’s why Jelastic uses a special Garbage Collection agent.
Jelastic GC agent works only for two kinds of Garbage Collection (set in Jelastic by default):
If you change the default GC settings to any other which does not provide compaction and can not release RAM to OS by design, then Jelastic GC Agent will be disabled and won’t call Full GC.
To tune the settings of Jelastic GC agent, navigate to the server > variables.conf file for Tomcat, TomEE or Jetty application server.
GC agent for GlassFish can be configured or disabled via the GlassFish admin panel in gfcluster-config > JVM Settings > JVM Options.
Enable/Disable Jelastic GC Agent
Jelastic GC agent is enabled for all newly created Java application servers by default.
If you want to enable Jelastic GC agent in already existing containers, you need to upload the jelastic-gc-agent.jar file and set the agent manually in the following way:
1. Download the jelastic-gc-agent.jar file.
2. Navigate to the Conf files of your Java server and upload the downloaded .jar file to the home folder.
3. Navigate to server > variables.conf file and state the path to your jelastic-gc-agent.jar file in the Java agent parameter.
The path can differ based on the Java server you use:
- Tomcat/TomEE: /opt/tomcat/temp
- GlassFish: /opt/glassfish3/temp
- Jetty: /opt/jetty/home
4. Save the changes and Restart the server.
If you think that Jelastic GC agent processes may cause performance degradation for your application, please comment the following line and restart the server:
Change the Period of Checks
By default, Jelastic GC agent initiates system checking every 15 minutes (beginning from every JVM start) to force freeing of unused application memory. The period of checks can be changed based on your requirements.
To change the time period of checks, specify the duration between calls of full GC in seconds, as shown below:
Save your edits and Restart the server to apply the changes.
Enable Debug Mode
You can also enable debug mode in the following way:
As a result, you’ll be able to track GC processes in the logs.
Save your changes and Restart the server.
Check GC Results
To check the result of the configured periodical checks and RAM releasing we are going to use a special Loader application.
1. Follow the link to download Loader.war archive with the testing application.
2. Upload this .war archive to the Jelastic Cloud.
3. Deploy this Loader application to the environment with the Java application.
4. Open Config files and navigate to server > variables.conf file in order to check the Jelastic Java agent settings.
In our case, we changed the period value to 60 seconds to get a faster result.
If you also edit the configurations, then do not forget to Save the changes and Restart the server.
5. After that, open the application in a browser and add the following parameters to the link:
6. Now you can navigate to the Statistics where after some time you’ll see the results.
When you request the application, the memory usage increases by 500 MB due to the parameters added to the app link. Such an amount of RAM is going to be used during 300 seconds (also due to stated parameter).
And after that, the memory usage will decrease as the Jelastic Java agent calls Full GC. This is performed because the Jelastic GC agent recognizes the possibility to release some RAM as the app completed its active processes and does not require the full amount of memory.
You can request the testing application again in order to load the memory several times and check the process of its release.
7. As we switched on the debug mode for our Java agent, we can also track the process in the Log files.
The amount of available free memory (in bytes) can be seen in the catalina logs
Hence, using this method, you can improve your application memory management which will lead to a reduction of RAM consumption by JVM. As a result, you will save your money and increase the performance of your application.
Proof that this is an effective solution, is from feedback on this functionality from one of our existing customers:
“I’m loving the new GC Agent! Look at the money it is saving!” – Katherine Morgan Demchinsky
That kind of feedback means so much to the team at Jelastic. It acknowledges that our commitment to making Jelastic better is useful and appreciated! Stay tuned to see what other new features and functions are added to Jelastic.