[OPENAM-12037] Memory leak: LDAPFilterCondition creates new ShutdownManager listener on each request Created: 02/Nov/17  Updated: 02/Jun/20  Resolved: 06/Nov/17

Status: Resolved
Project: OpenAM
Component/s: policy
Affects Version/s: 13.5.1, 14.0.0, 14.1.0, 14.1.1, 14.5.0
Fix Version/s: 13.5.2, 5.5.2

Type: Bug Priority: Major
Reporter: Nathalie Hoet Assignee: Mark de Reeper
Resolution: Fixed Votes: 0
Labels: EDISON
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File HeapdumpView.png    
Target Version/s:
Sprint: AM Sustaining Sprint 44
Story Points: 2
Needs backport:
No
Support Ticket IDs:
Needs QA verification:
No
Functional tests:
No
Are the reproduction steps defined?:
Yes and I used the same an in the description

 Description   

Bug description

When using the condition environment LDAPFilter OpenAM adds a ShutdownManager Listener repeatedly. ShutdownManager listeners are not removed until OpenAM is shutdown, so it creates a leak.

With subject time to live disabled and many LDAPFilter condition filters, the leak will be noticeable more quickly. But even with subject ttl enabled, new listeners would be added after the cache expire, creating a slow leak as well.

How to reproduce the issue

  1. Install OpenAM + agent + agent profile + policy
  2. Add a LDAP Filter condition environment to the policy
  3. Disable subject TTL in order to see an impact more quickly: in Services > Policy Configuration > Subjects result Time To Live > set to 0
  4. Access the protected resource (redirect to AM ; log user in; agent doing policy evaluation) -> policy evaluation being the key here.
  5. Load test and take a heap dump
Expected behaviour
Should see only a small footprint for the shutdownmanager
Current behaviour
ShutdownManager retained set increases regularly.

See screenshot. Impact shown on screenshot is minimal (0,52%), but shows already 11k+ entries. In the customer's case, there were 1.5 million such entries occupying 77% of retained heap after one day of running.

Code analysis

The setPolicyConfig method in the LDAPFilterCondition adds a new ShutdownManagerListener each time it is called (if cache is disabled or expired), although only one ShutdownManager is needed.

com.sun.identity.policy.plugins$LDAPFilterCondition.java#setPolicyConfig
LDAPConnectionPools.initConnectionPool(ldapServer,
        authid, authpw, heartBeatInterval, heartBeatTimeUnit, sslEnabled, minPoolSize, maxPoolSize, options);
connPool = LDAPConnectionPools.getConnectionPool(ldapServer);
ShutdownManager shutdownMan = com.sun.identity.common.ShutdownManager.getInstance();
shutdownMan.addShutdownListener(
        new ShutdownListener() {
            public void shutdown() {
                if (connPool != null) {
                    connPool.close();
                }
            }
        });

As the initConnectionPool already adds the listener and does that only once, the section adding the ShutdownManager can be removed.


Generated at Fri Nov 27 17:23:52 UTC 2020 using Jira 7.13.12#713012-sha1:6e07c38070d5191bbf7353952ed38f111754533a.