Uploaded image for project: 'XMLBeans'
  1. XMLBeans
  2. XMLBEANS-608

Memory leak in interface extension handling

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • Version 5.0.3
    • Version 5.1.0
    • None
    • None

    Description

      The following code in /xmlbeans/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java can leak memory:

          private class FileVisitor extends SimpleFileVisitor<Path> {
              @Override
              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                  if (javaMatcher.matches(file)) {
                      if (roots.stream().noneMatch(file::startsWith)) {
                          getRoot(file).ifPresent(r -> {
                              getSolver().add(new JavaParserTypeSolver(r, getParserConfiguration()));
                              roots.add(r);
                          });

      because the paths in roots are absolute paths at this point, but file may be a relative path. This means that the file::startsWith test always fails, and IIUC this means that a new JavaParserTypeSolver instance is created for every Java source file, for every interface extension. These instances can never be garbage-collected.

      For the project that I am currently trying to migrate from XMLBeans 3.1.0, I can run the schema compiler with -Xmx50g on a large memory server, and the heap still fills up in a few minutes.

      In my hands, the following patch fixes the problem and gives a huge performance boost as well:

      index 25003989..a19d495a 100644
      --- a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java
      +++ b/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java
      @@ -105,7 +105,7 @@ class ChildSolverCollectionStrategy implements CollectionStrategy {
               @Override
               public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                   if (javaMatcher.matches(file)) {
      -                if (roots.stream().noneMatch(file::startsWith)) {
      +                if (roots.stream().map(Path::toAbsolutePath).noneMatch(file.toAbsolutePath()::startsWith)) {
                           getRoot(file).ifPresent(r -> {
                               getSolver().add(new JavaParserTypeSolver(r, getParserConfiguration()));
                               roots.add(r);

      The difference can also be seen by giving absolute paths, not relative paths, for the directories containing Java source files to the schema compiler.

       

       

      Attachments

        Activity

          People

            Unassigned Unassigned
            pakeller Peter Keller
            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 - 10m
                10m