Uploaded image for project: 'Commons BCEL'
  1. Commons BCEL
  2. BCEL-317

Pluggable cache for ConstantUtf8

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 6.3.1
    • Fix Version/s: 6.4.0
    • Component/s: Main
    • Labels:
      None
    • Flags:
      Patch

      Description

      Please see the comment https://issues.apache.org/jira/browse/BCEL-317?focusedCommentId=16879552&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16879552 for resolution.


      Follow-up of BCEL-186. This enhancement is to provide an option to cache ConstantUtf8 instances that have the same value.

       

      Email thread: [bcel] Idea to share ConstantUtf8 of same value among JavaClass instances

      --------------------
      We use BCEL library to inspect Java class. Thank you for the great library.
       
      When our tool checks classes in ~200 jar files, it creates more than 2 million BCEL ConstantUtf8 instances. I suspect many of them share the same values such as "java.lang.String".
       

      Without cache, my tool created 2,6 million ConstantUtf8 instances (before failing OutOfMemoryError: GC overhead limit exceeded) to check ~200 jar files.

       

      With the cache, my tool created just 0.6 million ConstantUtf8 instances. It didn't throw the OutOfMemoryError.

       
      Old commit that made ConstantUtf8.getInstance https://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Constant.java?r1=1481383&r2=1481382&pathrev=1481383

      The ConstantUtf8.getInstance has been unused in BCEL since BCEL-186 http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantUtf8.java?r1=1652541&r2=1652540&pathrev=1652541

       

      How our project uses BCEL

      • Our tool (Linkage Checker) creates BCEL's ClassPathRepository with around 200 JAR files as its input class path in ClassDumper.createClassRepository(source code URL)
          private static Repository createClassRepository(List<Path> paths) {
            ClassPath classPath = new LinkageCheckClassPath(paths);
            return new ClassPathRepository(classPath);   # This is BCEL API
          }
      • reads JavaClasses one by one in ClassDumper.listClassesInJar (source code URL) through the ClassPathRepository.
          private ImmutableSet<JavaClass> listClassesInJar(Path jar) throws IOException {
            ImmutableSet.Builder<JavaClass> javaClasses = ImmutableSet.builder();
            for (String className : listClassNamesInJar(jar)) {
              try {
                JavaClass javaClass = classRepository.loadClass(className); # This is BCEL API. ConstantUtf8 is not cached.
                javaClasses.add(javaClass);
          ...(omit)
            return javaClasses.build();
          }

        Stacktrace from the ClassDumper.listClassesInJar to BCEL's ConstantUtf8.getInstance would look like this:

        ConstantUtf8.getInstance
        Constant.readConstant
        ConstantPool.<init>
        ClassParser.readConstantPool
        ClassParser.parse
        ClassPathRepository.loadClass
        ClassPathRepository.loadClass
        ClassDumper.listClassesInJar 

       

       

       

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              suztomo Tomo Suzuki
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 40m
                40m