JDK-8058541 : Massive memory use loading CRLs using CertificateFactory.generateCRL
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 7u5
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2008
  • CPU: x86
  • Submitted: 2012-08-23
  • Updated: 2014-09-16
  • Resolved: 2014-09-16
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b06)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.0.6002]

EXTRA RELEVANT SYSTEM CONFIGURATION :
W2k8 Server 64-bit OS with an Intel core 2 duo E8400 @ 3.00Ghz 2.99Ghz, with 4Gb RAM.

A DESCRIPTION OF THE PROBLEM :
This refers back to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6670894, which was never addressed.

It has gotten worse in Java versions from 1.6_21 on: In 1.6.0_17, about 95 MB of CRLs takes 1.33GB ( GB! ) of memory. Post 1.6.0_21, the same siize in CRLs takes roughly 1.45GB.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
load crl files using the code provided

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
lower memory use
ACTUAL -
approximately 14.5:1 memory use when laoding CRLs

ERROR MESSAGES/STACK TRACES THAT OCCUR :
OOM when loading CRLs in a J2EE Web Application. In general, massive memory use.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
import java.security.cert.*;
import javax.security.auth.x500.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.lang.Thread;

public class CRLLoader
{
    private static Map<X500Principal, X509CRL> crlList = new HashMap<X500Principal, X509CRL>();

    public static void main( String[] args )
    {
        String dirName = "C:/work/temp/cert-files/CRL_DIR/general/";
        ArrayList<File> newFiles = new ArrayList<File>();
        File dir = new File( dirName );

        try
        {
            CertificateFactory cf = CertificateFactory.getInstance("X509");

            FileInputStream crlFileStream = null;
            X509CRL crl = null;

            File[] crlFiles = dir.listFiles( new FileFilter()
            {
                @Override
                public boolean accept(File child)
                {
                    return child.isFile() && child.canRead() && child.getName().endsWith(".crl");
                }

            });

            for( File newFile : crlFiles )
            {
                try
                {
                    //Read the File
                    System.out.println("Adding CRL: " + newFile.toString());
                    crlFileStream = new FileInputStream(newFile);
                    crl = (X509CRL)cf.generateCRL(crlFileStream);
                    crlFileStream.close();

                    //and add to map
                    crlList.put(crl.getIssuerX500Principal(), crl);
                }
                catch( Exception e )
                {
                    System.out.println( e.toString() );
                    e.printStackTrace();
                }
            }
        }
        catch( Exception ex )
        {
            System.out.println( ex.toString() );
        }

        try
        {
            Thread.sleep( 10000 );
            System.gc();
            Thread.sleep( 10000 );
        }
        catch( InterruptedException ie )
        {
            System.out.println( ie.getMessage() );
        }
    }
}

---------- END SOURCE ----------

Comments
Closing as a duplicate of JDK-6670894
16-09-2014