Memory leak of JaasSecurityManager$DomainInfo in TimedCachePolicy on JBoss EAP
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 4.2.x
- 4.3.x
- 5.x
Issue
- Memory leaks in TimedCachePolicy, more specifically org.jboss.security.plugins.JaasSecurityManager$DomainInfo
Resolution
One solution is to disable authentication cache by adding an invalid JNDI name to prevent cache from being created
<attribute name="AuthenticationCacheJndiName">java:/nonexistent</attribute>
Another solution is to manually flush the entire authentication cache periodically with the following code:
MBeanServer server = MBeanServerLocator.locateJBoss();
String jaasMgrName = "jboss.security:service=JaasSecurityManager";
ObjectName jaasMgr = new ObjectName(jaasMgrName);
String domainName = "name"; //for example "jmx-console"
Object[] params = {domainName};
String[] signature = {String.class.getName()};
server.invoke(jaasMgr, "flushAuthenticationCache", params, signature);
To remove only one user entry from the cache, use the following code:
MBeanServer server = MBeanServerLocator.locateJBoss();
String jaasMgrName = "jboss.security:service=JaasSecurityManager";
ObjectName jaasMgr = new ObjectName(jaasMgrName);
String domainName = "name"; //for example "jmx-console"
Principal user = new SimplePrincipal("username");
Object[] params = {domainName, user};
String[] signature = {String.class.getName(), Principal.class.getName()};
server.invoke(jaasMgr, "flushAuthenticationCache", params, signature);
Another solution is to configure JBoss (>= 4.3.0.GA_CP07) to actively flush the authentication cache to avoid OutOfMemoryError errors. To enable this feature, you will need to add a DefaultCacheFlushPeriod attribute to the JaasSecurityManagerService MBean located in server/$PROFILE/conf/jboss-service.xml file. The attribute should look like this (set to 5 seconds for testing):
<attribute name="DefaultCacheFlushPeriod">5</attribute>
If still seeing large caching with flushing enabled, verify that the timeout is not set too large (1800 or 30 minutes is typically fine):
<attribute name="DefaultCacheTimeout">1800</attribute>
Root Cause
The authentication cache entries are not actively scanned to check if they are expired. All entries remain in the cache after timeout. They are lazily removed only the next time they are accessed, only to be replaced by the new entry. This pattern appears as a memory leak since entries are never really removed from the cache.
An exception to this behavior is a proper logout from a web application that has flushOnSessionInvalidation="true" in the security domain configuration in jboss-web.xml. This causes an entry to be removed from the cache. Note that session timeout does not flush the authencation cache as a proper session logout would. This can be addressed with the introduction of Content from jira.jboss.org is not included.Content from jira.jboss.org is not included.https://jira.jboss.org/jira/browse/JBPAPP-2312
Diagnostic Steps
- Troubleshoot with a heap dump as described in Java application "java.lang.OutOfMemoryError: Java heap space" to identify the source of retention
- If cache flushing is active, verify the entires are not being created with too large of a timeout. That can be verified in the heap dump with the OQL below:
SELECT s.defaultLifetime FROM org.jboss.security.auth.AuthenticationTimedCachePolicy s
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.