Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8085903

New fix for memory leak in ProtectionDomain cache

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8, 9
    • Fix Version/s: 9
    • Component/s: security-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b102
    • CPU:
      generic
    • OS:
      generic

      Backports

        Description

        Fix for JDK-8058547 failed in that it's caused a regression. See JDK-8077418.

        Using this record to code a new fix.

          Issue Links

            Activity

            Hide
            mullan Sean Mullan added a comment - - edited
            The memory leak occurs when custom Permissions are used in a policy file, for example:

            grant codeBase "file:${user.home}/app/" {
                permission SomePermission "foo";
            };

            In the example above, the SomePermission is created as an UnresolvedPermission instance when the policy file is initially parsed and then later resolved and instantiated as a SomePermission object when a permission check on SomePermission is triggered. It uses the same classloader of the SomePermission instance that is passed in. The policy file also caches the set of permissions granted to each ProtectionDomain. This cache avoids parsing the policy file and re-calculating the granted permissions each time a permission for a ProtectionDomain is checked.

            The memory leak occurs because the SomePermission class contains a strong reference to the ClassLoader which loaded it which in turn contains a strong reference to the ProtectionDomain associated with classes loaded by that ClassLoader, and which is also the key used in the cache. Because it is a loop of strong references, the entry will remain in the cache indefinitely, and each time a new ClassLoader is created that loads a custom Permission, another entry will be placed in the cache, etc. And this is true even though WeakReferences are currently used for the key, because the strong reference to the ProtectionDomain prevents them from being cleared.

            Thus, the most reasonable solution I have found is to wrap the PermissionCollection cache value in a SoftReference which will allow the PermissionCollection values to cleared by the GC if necessary. The code is written such that the PermissionCollection that has been GC-ed can be re-calculated by parsing the policy file again if necessary.
            Show
            mullan Sean Mullan added a comment - - edited The memory leak occurs when custom Permissions are used in a policy file, for example: grant codeBase "file:${user.home}/app/" {     permission SomePermission "foo"; }; In the example above, the SomePermission is created as an UnresolvedPermission instance when the policy file is initially parsed and then later resolved and instantiated as a SomePermission object when a permission check on SomePermission is triggered. It uses the same classloader of the SomePermission instance that is passed in. The policy file also caches the set of permissions granted to each ProtectionDomain. This cache avoids parsing the policy file and re-calculating the granted permissions each time a permission for a ProtectionDomain is checked. The memory leak occurs because the SomePermission class contains a strong reference to the ClassLoader which loaded it which in turn contains a strong reference to the ProtectionDomain associated with classes loaded by that ClassLoader, and which is also the key used in the cache. Because it is a loop of strong references, the entry will remain in the cache indefinitely, and each time a new ClassLoader is created that loads a custom Permission, another entry will be placed in the cache, etc. And this is true even though WeakReferences are currently used for the key, because the strong reference to the ProtectionDomain prevents them from being cleared. Thus, the most reasonable solution I have found is to wrap the PermissionCollection cache value in a SoftReference which will allow the PermissionCollection values to cleared by the GC if necessary. The code is written such that the PermissionCollection that has been GC-ed can be re-calculated by parsing the policy file again if necessary.
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/41491b4e93d1
            User: mullan
            Date: 2016-01-13 15:35:27 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/41491b4e93d1 User: mullan Date: 2016-01-13 15:35:27 +0000
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/41491b4e93d1
            User: lana
            Date: 2016-01-20 20:51:00 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/41491b4e93d1 User: lana Date: 2016-01-20 20:51:00 +0000

              People

              • Assignee:
                mullan Sean Mullan
                Reporter:
                coffeys Sean Coffey
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: