Skip to content

A lot of memory being held by org.bouncycastle.crypto.util.dispose.DisposalDaemon #2121

Closed

Description

@vhbcm

We are seeing a lot of memory being held by Bouncy Castle FIPS 2.1.0. See the attached screenshot from heap dump analysis:

Image

We did not observe the same behaviour with 1.0.x BC FIPS.

It seems all of the objects held are like this:

Image

Activity

  1. mwcw commented on Jul 7, 2025

    @mwcw
    Collaborator

    I need to provide some background first.

    The DisposalDaemon listens for notifications that an object is available to be garbage collected and releases any native allocations associated with that object.

    The original behaviour was to release native allocations as soon as a notification was received, however on busy JVMs especially where the machine has many (16+ cores) the JVM will flag an object as being available for collection while other threads are finishing up their last method call to that object.

    If the last method call involved calling a function that operated on an native allocation then the JVM would SegFault because because the pointers would be invalid.

    In the end the only way we could work around this was to delay cleanup by a fixed period of time.

    This delay is adjustable down to zero but the smaller you make the delay the bigger the risk you may run into a SegFault, I can't advise you what the best delay is because it is going to depend on usage and the hardware it is running on.

    You can use the property, org.bouncycastle.native.cleanup_delay to set the delay in seconds, the default is five.

    Thanks

    MW

  2. wilx commented on Jul 10, 2025

    @wilx

    It seems to me this is a quality of implementation issue. This should be solvable, on Java 9+ at least, without resorting to delaying tactics, using java.lang.ref.Reference.reachabilityFence() around the native calls.

  3. dghgit commented on Jul 10, 2025

    @dghgit
    Contributor

    2.1.0 has to support Java 8. It's possible, but not clear, that going multi-release could make a different approach possible, but at the time developing 2 different blocks of code for handling the gc issue in a multi-release fashion was well beyond the resources we had available to us.

  4. wilx commented on Jul 10, 2025

    @wilx

    Doug Lea had an implementation for the reachability fence. Even using synchronized would be cheaper than using the whole delaying scheduler ensemble. Implementing this as two separate classes, one default for Java 8 and another as for version 9 in Multi-Release JAR would improve things a lot.

  5. tmueller64 commented on Jul 28, 2025

    @tmueller64

    Is there any update on a schedule for getting this fixed? We are seeing the retained memory for the DisposalDaemon object growing to 285 MB after about a week of running bc-fips within Tomcat. Is there any workaround that can be used to release the memory? Thanks.

  6. dghgit commented on Jul 29, 2025

    @dghgit
    Contributor

    Try what's in: https://downloads.bouncycastle.org/betas/bc-fips-2.1.1-SNAPSHOT.zip

    We think we may have caused some GC confusion by using a private inner class. This should fix it (assuming that is the problem).

  7. tmueller64 commented on Aug 2, 2025

    @tmueller64

    I ran our application on Tomcat 10 using the 2.1.1-SNAPSHOT build above and the JVM memory problem is solved. Thanks.

  8. dghgit commented on Aug 3, 2025

    @dghgit
    Contributor

    That's a relief! 2.1.1 has been published to Maven Central, note the release is not officially certified, and should be treated as an "update stream" release for FedRAMP purposes. We're talking to our lab about making sure it's officially recognized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    support requestCommunity assistance requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions