Skip to content

Lookup.loadCertificateOrCRLFile consumes more memory because of frequent memory allocation at Certificate.matches #86

Closed
@frsyuki

Description

@frsyuki

Overview

  • Since jruby-openssl 0.9.8, Lookup.loadCertificateOrCRLFile calls Store.matchedObject, and it calls Certificate.matches method for each stored certificates.
  • Certificate.matches method calls x509.getSubjectX500Principal() method. This method internally encodes aux certificate using Bouncy Castle's ASN1OutputStream.
  • This encoding procedure creates many objects.
  • It impacts GC performance badly.

Background

We upgraded JRuby 9.0.0.0 to 9.0.5.0 and found that our application started consuming much more memory. This application uses httpclient.gem to fetch data from HTTPS server. Here is its code:
https://github.com/treasure-data/embulk-input-sfdc/blob/master/lib/embulk/input/sfdc_api/api.rb

Here is a screenshot of memory profiler:

  • JRuby 9.0.0.0 (which uses jruby-openssl v0.9.7)
  • JRuby 9.0.5.0 (which uses jruby-openssl v0.9.11)

This shows that 9.0.5.0 allocates objects more frequently and triggers GC frequently (2x - 3x more frequent).

Memory profiler shows that under Lookup.loadCertificateOrCRLFile method, JRuby 9.0.0.0 doesn't allocate many objects but 9.0.5.0 allocates many objects at Store.addCertificate in addition to regular allocation at PEMInputOutput.readPEM:

  • JRuby 9.0.0.0
  • JRuby 9.0.5.0

Under Store.addCertificate, following stack is allocating majority of objects:

  • Store.matchedObject
    • Certificate.matches
      • X509AuxCertificate.getSubjectX500Principal
        • ASN1OutputStream.writeObject
          • DERSequence.encode
            • ...

I think that Store.matchedObject method is just a lookup method but X509AuxCertificate.getSubjectX500Principal is allocating many objects unexpectedly.

Expected behavior

I think that Store.matchedObject or Certificate.matches can cache the result of X509AuxCertificate.getSubjectX500Principal() to reduce object allocation.

Workaround

Memory allocation becomes much less frequent if I add jruby.openssl.x509.lookup.cache=8 system property:

  • JRuby 9.0.5.0 + jruby.openssl.x509.lookup.cache=8

But this option is disabled by default now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions